home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -screenplay- / otherstuff / jst_dev / docs / engonly / jotdstartup.doc < prev    next >
Text File  |  1999-04-20  |  85KB  |  2,937 lines

  1. TABLE OF CONTENTS
  2.  
  3. JOTDStartup/JOTD HD Startup code autodocs
  4. JOTDStartup/Memory setup
  5. JOTDStartup/Calling the user code
  6. JOTDStartup/Useful macros
  7. JOTDStartup/STORE_REGS-RESTORE_REGS
  8. JOTDStartup/Console output
  9. JOTDStartup/PatchMacros
  10. JOTDStartup/CallMacros
  11. JOTDStartup/Compelling Macros
  12. JOTDStartup/MiscMacros
  13. JOTDStartup/Relocatable Memory operations
  14. JOTDStartup/Registers: CAUTION!
  15. JOTDStartup/JoypadState()
  16. JOTDStartup/GetUserData()
  17. JOTDStartup/SetLocalVarZone()
  18. JOTDStartup/SetFilesPath()
  19. JOTDStartup/UseHarryOSEmu()
  20. JOTDStartup/ReadUserDir()
  21. JOTDStartup/SaveOSData()
  22. JOTDStartup/Reboot()
  23. JOTDStartup/AllocExtMem(), Alloc24BitMem()
  24. JOTDStartup/OpenFakeExec()
  25. JOTDStartup/FreezeAll()
  26. JOTDStartup/LoadDisks()
  27. JOTDStartup/LoadDisksIndex()
  28. JOTDStartup/LoadDiskFromName()
  29. JOTDStartup/LoadSmallFiles()
  30. JOTDStartup/LoadFiles()
  31. JOTDStartup/GetFileLength()
  32. JOTDStartup/TestFile()
  33. JOTDStartup/TestFileAbs()
  34. JOTDStartup/LoadRNCFile()
  35. JOTDStartup/TransfRoutines()
  36. JOTDStartup/BlockFastMem()
  37. JOTDStartup/Degrade()
  38. JOTDStartup/Enhance()
  39. JOTDStartup/DegradeGfx()
  40. JOTDStartup/DegradeCpu()
  41. JOTDStartup/Display()
  42. JOTDStartup/CloseAllQuiet()
  43. JOTDStartup/CloseAll()
  44. JOTDStartup/FlushCachesSys()
  45. JOTDStartup/GetMemFlag()
  46. JOTDStartup/TestxMbChip()
  47. JOTDStartup/CheckAGA()
  48. JOTDStartup/GetSR()
  49. JOTDStartup/GetAttnFlags()
  50. JOTDStartup/WriteFileHD()
  51. JOTDStartup/WriteUserFileHD()
  52. JOTDStartup/ReadUserFileHD()
  53. JOTDStartup/ReadFile()
  54. JOTDStartup/ReadFilePart()
  55. JOTDStartup/ReadFilePartHD()
  56. JOTDStartup/ReadFileHD()
  57. JOTDStartup/DeleteFileHD()
  58. JOTDStartup/DeleteUserFileHD()
  59. JOTDStartup/InGameOSCall()
  60. JOTDStartup/PatchExceptions()
  61. JOTDStartup/FlushCachesHard()
  62. JOTDStartup/GoECS()
  63. JOTDStartup/ResetDisplay()
  64. JOTDStartup/ResetSprites()
  65. JOTDStartup/KickVerTest()
  66. JOTDStartup/Kick37Test()
  67. JOTDStartup/InitTrackDisk()
  68. JOTDStartup/TrackLoad
  69. JOTDStartup/SetTDUnit()
  70. JOTDStartup/ReadFileFast()
  71. JOTDStartup/ReadRobSectors()
  72. JOTDStartup/ReadDiskPart()
  73. JOTDStartup/StrcpyAsm()
  74. JOTDStartup/StrcmpAsm()
  75. JOTDStartup/StrlenAsm()
  76. JOTDStartup/ToUpperAsm()
  77. JOTDStartup/HexReplaceLong()
  78. JOTDStartup/HexReplaceWord()
  79. JOTDStartup/SetFakeFunction()
  80. JOTDStartup/CRC16()
  81. JOTDStartup/HexToString()
  82. JOTDStartup/Save & Restore hardware registers
  83. JOTDStartup/RNCLength()
  84. JOTDStartup/RNCDecrunch()
  85. JOTDStartup/RNCDecrunchEncrypted()
  86. JOTDStartup/ATNDecrunch()
  87. JOTDStartup/PPDecrunch()
  88. JOTDStartup/FungusDecrunch()
  89. JOTDStartup/BlackScreen()
  90. JOTDStartup/EnterDebugger()
  91. JOTDStartup/SetTraceVector()
  92. JOTDStartup/WaitMouse()
  93. JOTDStartup/WaitMouseInterrupt()
  94. JOTDStartup/InGameExit()
  95. JOTDStartup/IsRegistered()
  96. JOTDStartup/SetExitRoutine()
  97. JOTDStartup/InGameIconify()
  98. JOTDStartup/PatchMoveCList_Abs()
  99. JOTDStartup/PatchMoveCList_Ind()
  100. JOTDStartup/PatchMoveCList_Idx()
  101. JOTDStartup/PatchMoveBlit_Idx()
  102. JOTDStartup/StoreCopperPointer()
  103. JOTDStartup/TellCopperPointer()
  104. JOTDStartup/BeamDelay()
  105. JOTDStartup/WaitBlit()
  106. JOTDStartup/SetQuitKey()
  107. JOTDStartup/SetIconifyKey()
  108. JOTDStartup/LogPatch()
  109. JOTDStartup/InitLogPatch()
  110. JOTDStartup/The printlog tool
  111. JOTDStartup/JOTD HD Startup code autodocs
  112.  
  113.  
  114. ***************************************************************************
  115.  
  116.                         JOTD Startup V2.1-B
  117.             © Copyright 1995-99 Jean-François Fabre/Ralf Huvendiek
  118.  
  119. ***************************************************************************
  120.  
  121.  
  122.          Memory setup           
  123.          Starting your code     
  124.          Why decrunch routines ?
  125.  
  126.          Macros                 
  127.          Library Functions      
  128.  
  129.          The printlog tool      
  130.  
  131.          Contact us             
  132.  
  133.  
  134. -----------------------------------------------------------------------------
  135. Converted using GuideML V1.6, a converter written by Richard Körber
  136. <shred@chessy.aworld.de>
  137.  
  138.  
  139. JOTDStartup/Memory setup
  140.  
  141.  
  142. To understand some choices and notions, you have to know how the memory
  143. is organized by my loading routines:
  144.  
  145. On a fastmem amiga:
  146.  
  147. V39:
  148.  
  149. High Fast: User object, General reloc routines, disks images or RAM files,
  150.            OS chip mirror, extension mem (for the 1MB games) (if any)
  151. Fast: The JOTDStartup program routines not relocated.
  152. Low Chip: The game (can take 512K, 1024K or 2048K)
  153.  
  154. Older than V39:
  155.  
  156. Fast: User object, General reloc routines, disks images or RAM files,
  157.            OS chip mirror, extension mem (for the 1MB games) (if any),
  158.            the HD load program
  159. Low Chip: The game (can take 512K, 1024K or 2048K)
  160.  
  161.  
  162. On a chip only amiga (V39):
  163.  
  164. High Chip: User object, General reloc routines, disks images or RAM files,
  165.            OS chip mirror, extension mem (for the 1MB games) (if any)
  166. Chip: The game, The JOTDStartup program routines not relocated.
  167.  
  168. Obviously, while the game is running, you cannot call non-relocated routines
  169. (the ones callable with JSRABS), or else it will crash. You won't need
  170. those routines anyway during the game (you can use JSRABS routines in
  171. a code called using InGameOSCall)
  172.  
  173. If the game needs more than 512K to run, you'll have to find where the expansion
  174. memory detection is done to replace it by a pointer on the extension mem you allocated
  175. with AllocExtMem(), else the game can crash (older than V39)
  176.  
  177. The NOFAST tooltype will try to allocate chipmem for AllocExtMem unless you've got
  178. no chipmem above $80000 (the assumed chip size before you make a SaveOSData())
  179. In this case it will return 0 (it's useless to allocate mem that will be overwritten by
  180. the game)
  181.  
  182. Note: If you succeed in tracking the game memory 'allocation', you don't need relocatable
  183. routines, and nothing will overwrite your code,
  184. but it depends on which level of quality you want when you program your installers...
  185. And this is also compulsory if you want to install a clean quit option!
  186.  
  187. In the case you would like to leave some OS code done by the game, JST supports ExecBase
  188. emulation since V0.7. Some calls are supported, others are redefinable by the user,
  189. (see OpenFakeExec() function)
  190.  
  191.  
  192.  
  193.  
  194. JOTDStartup/Calling the user code
  195.  
  196.  
  197. Your relocatable object file will be loaded by JST and it will be checked
  198. against relocatable symbols. For instance, you cannot do things like:
  199.  
  200. move.l #20,var
  201. because this instruction needs relocation, and we can't afford it since
  202. JST is not yet able to do this. Instead you can use one of the reloc macros.
  203. This instruction will become:
  204.  
  205. RELOC_MOVEL #20,var
  206. JST passes some arguments in registers:
  207.  
  208. D0.L: 0 if no trainer detected via tooltypes/args, -1 if trainer requested
  209. D1.L: 0 if OS swap is allowed, -1 if not (see InGameOsCall())
  210. D2.L: -1 if JOYPAD is set in the tooltypes, 0 else 
  211. D3.L: -1 if HDLOAD is set in the tooltypes, 0 else 
  212. D4.L: -1 if BUTTONWAIT is set in the tooltypes, 0 else 
  213. D5.L: -1 if LOWMEM is set in the tooltypes, 0 else 
  214.  
  215. The others (function tables) are passed in the HD_PARAMS structure.
  216. Use the macros, and don't fool with the variables in HD_PARAMS.
  217.  
  218.  
  219.  
  220.  
  221. JOTDStartup/Useful macros
  222.  
  223.  
  224. Some of these macros are compulsory for a good compilation and linking
  225. of the user program. They are compatible with phxass and should cause no
  226. problem with other assemblers.
  227.  
  228.  
  229.          STORE_REGS          
  230.          RESTORE_REGS        
  231.  
  232.          Mac_printf          
  233.          PUTS                
  234.          NEWLINE             
  235.  
  236.          GETUSRADDR          
  237.          GETGENADDR          
  238.          PATCHUSRJMP         
  239.          PATCHUSRJSR         
  240.          PATCHABSJMP         
  241.          PATCHABSJSR         
  242.          PATCHGENJMP         
  243.          PATCHGENJSR         
  244.  
  245.          JSRGEN              
  246.          JSRGEN_FREEZE       
  247.          JMPGEN              
  248.          JSRABS              
  249.          JMPABS              
  250.  
  251.  TESTFILE            
  252.  WAIT_BLIT           
  253.  BEAM_DELAY          
  254.  GETLVO              
  255.  WAIT_JOY            
  256.  WAIT_LMB            
  257.  
  258.  HDPARAMS            
  259.  SAVEOS_DATA         
  260.  SET_VARZONE         
  261.  
  262.  RELOC_MOVEL         
  263.  RELOC_MOVEW         
  264.  RELOC_MOVEB         
  265.  RELOC_CLRL          
  266.  RELOC_CLRW          
  267.  RELOC_CLRB          
  268.  RELOC_STL           
  269.  RELOC_STW           
  270.  RELOC_STB           
  271.  RELOC_TSTL          
  272.  RELOC_TSTW          
  273.  RELOC_TSTB          
  274.  RELOC_SUBL          
  275.  RELOC_SUBW          
  276.  RELOC_SUBB          
  277.  RELOC_ADDL          
  278.  RELOC_ADDW          
  279.  RELOC_ADDB          
  280.  
  281.  Using registers     
  282.  
  283.  
  284.  
  285.  
  286. JOTDStartup/STORE_REGS-RESTORE_REGS
  287.  
  288.  
  289. STORE_REGS
  290. Save all the registers to stack (D0 to A6)
  291.  
  292. RESTORE_REGS
  293. Restore all the registers from stack (D0 to A6)
  294.  
  295. No parametrers expected.
  296.  
  297.  
  298.  
  299.  
  300. JOTDStartup/Console output
  301.  
  302.  
  303. Mac_printf:
  304.  
  305. Prints messages with an easy syntax in an assembly program. Avoids label definition,
  306. and all the problems going with it.
  307.  
  308. Mac_printf "Hello world"
  309. Mac_printf "You are ",jkjdkfj
  310. Mac_printf "a hd-installer maniac"
  311.  
  312. will display on the console:
  313.  
  314. Hello world
  315. You are a hd-installer maniac
  316.  
  317. If you use 2 arguments in the macro, there will be no linefeed.
  318.  
  319.  
  320. PUTS:
  321.  
  322. Puts a string on the screen
  323. Argument: string pointer.
  324.  
  325. NEWLINE:
  326.  
  327. Just skips a line. No argument needed.
  328.  
  329.  
  330. Note: Those macros use the Display() routine.
  331.  
  332.  
  333.  
  334.  
  335. JOTDStartup/PatchMacros
  336.  
  337.  
  338. GETUSRADDR
  339. Returns in D0 the relocated address of a routine in the user code.
  340. This avoids a lea addr(pc),A0 then move.l A0,D0, but is not really useful anymore in
  341. the JST environnement.
  342.  
  343. GETGENADDR
  344. Returns (in D0) the address of a relocated general purpose routine.
  345.  
  346. Example:
  347.  
  348. lea $1456(A1),A0
  349. GETGENADDR ReadRobSectors
  350. move.w #$4EF9,(A0)+
  351. move.l D0,(A0)+
  352.  
  353. PATCHUSRJMP
  354. Sets a JMP to a given user relocatable address. The patched location is absolute.
  355. It may be used for chipmem, but not for extension mem, since you cannot know the
  356. absolute address (you have to calculate it). Do it by hand in this case.
  357.  
  358. PATCHUSRJSR
  359. Same thing, but with a JSR
  360.  
  361. PATCHABSJMP
  362. PATCHABSJSR
  363. Obsolete. Same thing as PATCHUSRJMP/JSR
  364.  
  365. PATCHGENJMP
  366. Sets a JMP in the general purpose relocated area (i.e. the functions of this
  367. library callable with JSRGEN)
  368.  
  369. PATCHGENJSR
  370. Same thing, for JSRs
  371.  
  372.  
  373.  
  374.  
  375. JOTDStartup/CallMacros
  376.  
  377.  
  378. JSRGEN
  379. JSRGEN_FREEZE
  380. JMPGEN
  381. Calls a relocated general purpose function.
  382.  
  383. E.g: JSRGEN TrackLoad
  384.  
  385. Those macros use A5 to get the function address. This register is restored.
  386.  
  387. JSRGEN_FREEZE can be useful if A5 (and also other registers used by the JST function)
  388. is used during interrupts.
  389. This macro freezes all the interrupts by setting SR to $2700 (means that
  390. you've got to be in superuser mode to use it), executes
  391. the function, then restores SR. I had to use it in Menace and Lotus Turbo Challenge.
  392.  
  393. JSRABS
  394. JMPABS
  395. Calls a absolute general purpose subroutine
  396.  
  397. E.g: JSRABS LoadDisks
  398.  
  399.  
  400.  
  401.  
  402. JOTDStartup/Compelling Macros
  403.  
  404.  
  405. Those macros are used in (almost) every loader.
  406.  
  407. GO_SUPERVISOR
  408. Calls the Supervisor exec routine and stores the userstack in a variable.No argument needed.
  409. Since v1.1d GO_SUPERVISOR can be called twice safely (there's a check for user mode)
  410.  
  411. SAVE_OSDATA
  412. Calls SaveOSData() with the chipmem you want to be saved.
  413. If you want to save 512K chipmem, type
  414. SAVE_OSDATA $80000
  415.  
  416. Passing $200000 to the function will allocate as much as chipmem possible, and
  417. mirror only the other parts (0-low boundary and high boundary-$200000)
  418.  
  419. If you want to save all the 2MB of chipmem:
  420.  
  421. SAVE_OSDATA $200000
  422.  
  423. This will allocate a big block of chipmem, and this block won't have to be mirrored.
  424.  
  425. Passing 2 arguments to SAVE_OSDATA will activate autoquit key feature.
  426. The 2nd argument is the autoquit key that you want to use (raw keycode)
  427.  
  428. Passing 3 arguments to SAVE_OSDATA will allow you to specify some custom user code
  429. you want called on exit (just like in SetExitRoutine())
  430. The 3rd argument is the address of the custom routine.
  431.  
  432. HD_PARAMS
  433. A compulsory macro which declares some variables, and also set tags for JST to read
  434. and write data and also recognize the loader.
  435.  
  436. HD_PARAMS "game.d",filesize,number of disks
  437.  
  438. The filesize can be set to STD_DISK_SIZE (901120) for normal trackload copiable disks.
  439. See the examples.
  440.  
  441. In diskfile mode, this call makes JST expect the diskfiles to be named game.d1, game.d2, etc...
  442. In files mode, the first argument allows to specify the subdir where the data files are
  443. to be located. (But you can also use SetFilesPath() to set the subdir too)
  444.  
  445. For a loader using files located in the same directory as the loader:
  446.  
  447. HD_PARAMS "",0,0
  448.  
  449.  
  450.  
  451. WARNING: This macro has 3 arguments. It's not possible to choose the window name any more.
  452. An error message will show up when assembling if you put the wrong number of arguments.
  453.  
  454. SET_VARZONE:
  455.  
  456. A macro useful in the case you want to add snapshot option to your loader and you've got local
  457. variables that you need to save in the loader (e.g. current disk unit, some flags...)
  458.  
  459. Put it everywhere you want. The best thing is to put it right after HD_PARAMS macro.
  460. The code will be executed even before your loader code.
  461.  
  462. This macro consists in a simple JSRABS SetLocalVarZone, with in A0 the start location of the
  463. variables (argument 1 of the macro) and in A1 the end location of the variables (argument 2
  464. of the macro).
  465.  
  466. All registers are preserved.
  467.  
  468. If you pass invalid values to this routine (e.g start after end) JST will tell it and quit.
  469.  
  470.  
  471.  
  472.  
  473. JOTDStartup/MiscMacros
  474.  
  475.  
  476. WAIT_LMB:
  477.  
  478. A simple left mouse button pause (port 0).
  479.  
  480. WAIT_JOY:
  481.  
  482. A simple joystick button pause (port 1).
  483.  
  484.  
  485. TESTFILE:
  486.  
  487. Calls the TestFile() function, with relocatable argument.
  488.  
  489. TESTFILE fname
  490. tst.l D0
  491. bne FileError
  492.  
  493. Actually this routine takes D0 as input and that's a bit annoying since in a relocatable
  494. environment we have to lea (pc) in an address register then move to D0 and call the routine.
  495. I don't want to change the way the routine works (backwards compatibility)
  496. but this little macro makes life easier.
  497.  
  498.  
  499. GETLVO:
  500.  
  501. A simple macro to get LVO offset in D0.
  502.  
  503. Example:  GETLVO   AvailMem   will return negative offset of AvailMem
  504.  
  505. Intended to use with SetFakeFunction()
  506.  
  507.  
  508. WAIT_BLIT
  509.  
  510. A macro to wait for the blitter operation to end (equivalent to WaitBlit
  511. but does not use any registers, useful for games which use/modify registers
  512. in interrupts)
  513.  
  514. BEAM_DELAY
  515.  
  516. A macro to wait using the vertical beam. Takes one argument.
  517.  
  518. BEAM_DELAY 1
  519.  
  520. will wait approx. 20 ms (PAL)
  521.  
  522.  
  523.  
  524.  
  525.  
  526. JOTDStartup/Relocatable Memory operations
  527.  
  528.  
  529. RELOC_MOVEL/W/B:
  530.  
  531. A macro which allows to move some data in an address specified by a label, but in a relocatable
  532. way:
  533.  
  534. move.l D0,label ; is not relocatable and JST will refuse it
  535.  
  536. move.l A6,-(sp)
  537. lea label(pc),A6
  538. move.l D0,(A6) ; is relocatable. but a pain to write
  539. move.l (sp)+,A6
  540.  
  541. That's what RELOC_MOVEL does.
  542.  
  543. For Word and Byte format, similar macros known as RELOC_MOVEW and RELOC_MOVEB exist.
  544.  
  545. RELOC_TSTL/W/B:
  546.  
  547. With the 68020+ instruction set, it's possible to test a label in a relocatable way:
  548.  
  549. tst.l label(pc)
  550.  
  551. But with the 68000 this is not possible. So I made a useful macro:
  552.  
  553. RELOC_TSTL label
  554.  
  555.  
  556. RELOC_CLRL/W/B:
  557.  
  558. Makes a RELOC_MOVE/W/B #0 to location
  559.  
  560. RELOC_ADDL/W/B:
  561. RELOC_SUBL/W/B:
  562.  
  563. relocatable add/sub
  564.  
  565.  
  566.  
  567.  
  568. JOTDStartup/Registers: CAUTION!
  569.  
  570.  
  571. Be careful not to use registers A5 and A6 with some macros, because they
  572. often use those registers: e.g:
  573.  
  574.         PATCHUSRJMP     ($30,A5),PatchLoader
  575. will crash because PATCHUSRJMP uses A5. This is subject to change, though.
  576. To change working registers (A5,A6) used in the macros to lets say (A3,A4),
  577. just include the following lines BEFORE the jst.i include.
  578.  
  579. REDEFINED_REGISTERS = 1 ; to tell jst.i that we've redefined the registers
  580. Ax EQUR A3 ; work register #1
  581. Ay EQUR A4 ; work register #2
  582.  
  583.  
  584. Or manually:
  585.  
  586.         move.l   A0,-(sp)
  587.         move.l   A5,A0
  588.         PATCHUSRJMP      ($30,A0),PatchLoader
  589.         move.l   (sp)+,A0
  590.  
  591.  
  592.  
  593.  
  594.  
  595. JOTDStartup/JoypadState()
  596.  
  597.  
  598. ULONG JoypadState(port)
  599.  D0                D0
  600.  
  601. This routine allows to check CD32 joypad buttons. It obviously does not use
  602. lowlevel.library and is buggy unless on a CD32 (why???). It's ripped from
  603. James Pond 3 routine (I was not the first since the ReadJoypad.s from aminet
  604. was also ripped from this one).
  605.  
  606. port can be 0 (mouse port) or 1 (joystick port).
  607.  
  608. The routine returns bits that you can test. The bits are defined in gp_macros.i
  609.  
  610. moveq #0,D0
  611. JSRGEN JoypadState
  612. btst #AFB_START ; start/pause button
  613. beq nostart$
  614. ...
  615.  
  616. On a normal amiga, you've got to go in a direction to make this routine work.
  617. I don't know why, but it works perfectly on a CD32.
  618. Also, you can't press fire (red button) and the other buttons together, or only fire
  619. will be detected.
  620.  
  621. You have to wait for a vertical blank to occur before you can use this function.
  622. I suggest that you put it in the level 3 interrupt, just before acknowledge
  623. (which is a move in $DFF09C) and set the flags here. Then another routine will
  624. check those flags and emulate game keys such as pause, jump/fire, etc... it's
  625. up to you :)
  626.  
  627. NOTE:
  628.  
  629. If you only want to check the second button (blue, or Sega joystick 2nd button),
  630. you can also read $DFF016 and check for bit 14 low, still after a VBLANK.
  631. Don't forget to reset the potgo in that case by
  632.  
  633. move.w #$CC01,($DFF034)
  634.  
  635. See also:
  636.  
  637.  
  638.  
  639.  
  640. JOTDStartup/GetUserData()
  641.  
  642.  
  643. APTR GetUserData(void)
  644.  A0
  645.  
  646. This routine returns in A0 a pointer to the NULL terminated string passed by
  647. the USERDATA argument or tooltype. It points to an empty string if USERDATA
  648. was not filled. It's useful to set a swith other than the user ones already present
  649. such as TRAINER, JOYPAD... and some info can be passed (it's not only a switch)
  650.  
  651. I used it in the Awesome JST ripper to specify the disk, side and drive unit.
  652.  
  653. See also:
  654.  
  655.  
  656.  
  657.  
  658. JOTDStartup/SetLocalVarZone()
  659.  
  660.  
  661. void SetLocalVarZone(start,end) - Sets saveable variable location in the loader
  662.                        A0  A1
  663.  
  664. When you make a snapshot, you save JST internal memory and the game internal memory,
  665. but you may also need to save some data relevant to your loader (e.g. current disk).
  666.  
  667. You may not need this routine if your loader is completely state-independent
  668. (i.e. does not require variables to work)
  669.  
  670. Extension memory pointer does not count as it's restored by the snapshot.
  671. No need to save this one.
  672.  
  673. Always call this routine before SAVE_OSDATA (or use the SET_VARZONE macro)
  674.  
  675. See also: InGameIconify, SET_VARZONE (macro)
  676.  
  677.  
  678.  
  679.  
  680. JOTDStartup/SetFilesPath()
  681.  
  682.  
  683. void SetFilesPath(dirname) - Changes default path for files to load to wished value
  684.                      A0
  685.  
  686. The first argument of HD_PARAMS can no longer be the subdir where the data files are
  687. to be loaded.
  688.  
  689. Use SetFilesPath instead. This function will change the load directory.
  690.  
  691. See also:
  692.  
  693.  
  694.  
  695.  
  696. JOTDStartup/UseHarryOSEmu()
  697.  
  698.  
  699. void UseHarryOSEmu(void) - allows the use of Harry's excellent OS emulation program
  700.  
  701. This function will allow you to use Harry's OS emulation program.
  702. This program must be called OSEmu.400 and be located in the C: directory.
  703.  
  704. This function allows a very powerful emulation, actually much better and complete
  705. than my OpenFakeExec() function!!
  706.  
  707. Read the documentation in the source code of OSEmu.asm for more details and refer
  708. to the JST loaders examples.
  709.  
  710. QUITKEY tooltype allows to change the default quit key (which is '*' of the numerical
  711. keyboard, provided that the keyboard is US/German. Actually this key is the upper right
  712. key of the numeric keypad, sorry A600 users :) )
  713.  
  714. See also: OpenFakeExec()
  715.  
  716.  
  717.  
  718.  
  719. JOTDStartup/ReadUserDir()
  720.  
  721.  
  722. ULONG ReadUserDir(dirname, buffer, maxentries, maxnamelen) - Reads dir from the user dir
  723.  D0                 A0       A1       D0          D1
  724.  
  725. This function will read the files in the directory specified in A0. The SAVEDIR value
  726. will be concatenated in the path if SAVEDIR is provided in the tooltypes (OS 2.0+ only)
  727.  
  728. The filenames will be copied in the output buffer specified in A1.
  729. Please note that only the plain files will be copied. Directories will be ignored.
  730.  
  731. This function will return the number of plainfiles in the directory in D0.
  732.  
  733. maxentries will allow to limit the number of files to be copied. It will prevent a buffer
  734. overflow. Set it to 0 if you don't want any limit.
  735.  
  736. maxnamelen will allow to limit the filename length. Set it to 0 and the limit will be 20
  737. characters.
  738. The filenames will be NULL terminated in the buffer, and spaced by maxnamelen bytes, even
  739. if the filenames are not that long, to allow easy search in the buffer.
  740.  
  741. e.g set maxnamelen to 32 ($20), and call ReadUserDir. The buffer will look like:
  742.  
  743. $00: f i r s t _ f i l e0 *rubbish*
  744. $20: s e c o n d _ f i l e0 *rubbish*
  745. $40: t h i r d _ f i l e0 *rubbish*
  746.  
  747. and so on...
  748.  
  749. I found it more convenient than a buffer depending on the actual length of the filenames,
  750. because a simple MULU allows to access any filename.
  751.  
  752.  
  753. See also: InGameOSCall()
  754.  
  755.  
  756.  
  757.  
  758. JOTDStartup/SaveOSData()
  759.  
  760.  
  761. void SaveOSData(chipmem_size,memsave) - Saves chipmem and custom & cia registers...
  762.                      D0        D1
  763.  
  764. Usually called by the SAVE_OSDATA macro.
  765.  
  766. The most important routine of JST package. You've got to understand it
  767. fully if you want to make a clean loader.
  768.  
  769. Useful for debug purposes and to be able to quit the game and make in-game
  770. OS calls (read/write files)
  771.  
  772. The memsave parameter is only used when the chipmem_size is $200000
  773. (AGA game loaded). If set to 0, SaveOSData will alloc the bigger chipmem
  774. chunk as possible and will therefore not care about this part of memory,
  775. so the save buffer in fastmem will be a lot smaller than 2MB.
  776. If set to -1, all chipmem will be saved. If DEBUG is set, memsave
  777. will also be set to -1 and you'll need more memory.
  778.  
  779. To save 1024K of chipmem:
  780.  
  781.      SAVE_OSDATA     $100000
  782.  
  783. To save 2048K of chipmem, trying to reduce fast memory consumption:
  784.  
  785.      SAVE_OSDATA     $200000
  786.  
  787.  
  788. If no memory is available, the chipmem won't be saved, and it won't be possible
  789. to quit the game/to get debug information.
  790. As a side effect, this function disables all interrupts/DMA this way:
  791.  
  792.     lea      #$DFF000  
  793.     move.w   #$4000,intena(A6)
  794.     move.w   #$7FFF,intreq(A6)
  795.     move.w   #$4020,dmacon(A6)   ; also remove sprite DMA
  796.  
  797. This is necessary as the system could keep on modifying and restoring chipmem could
  798. crash the machine. If your game bootup does not like the interrupts to be disabled,
  799. reactivate necessary interrupts/dma yourself.
  800.  
  801. SAVING MEMORY FOR A 2MB CHIP GAME
  802.  
  803. (If you can avoid to use the full 2MB of chip do it)
  804.  
  805. Trying to save 2MB of chip will activate the memsave option.
  806. This option consists in allocating as much as chipmem as possible, to avoid
  807. to allocate a whole block of 2MB fastmem. The allocated chipmem can be trashed
  808. by the game, it will not corrupt the system.
  809.  
  810. Be careful when you read or write a file to hard disk, because data may not match
  811. (addresses are translated to the fastmem chip mirror during an OS swap
  812. and the gap caused by the memsave option can 'corrupt' data).
  813. If you plan to activate memsave and read/save files to HD, do the disk IO
  814. in a fastmem buffer rather than in chipmem, and transfer it later (that's
  815. why you can read the HDLOAD/LOWMEM flag in the user code)
  816.  
  817. With diskfiles, check and display an error message if LOWMEM is on, because of
  818. the same problem, but you can't be sure if the bigger load part the game can
  819. do at a time...
  820.  
  821. See also: GO_SUPERVISOR, InGameExit, InGameOSCall, ReadFileHD, WriteFileHD
  822.  
  823.  
  824.  
  825.  
  826. JOTDStartup/Reboot()
  827.  
  828.  
  829. Just reboots the computer (the OS must be active)
  830.  
  831.  
  832.  
  833.  
  834. JOTDStartup/AllocExtMem(), Alloc24BitMem()
  835.  
  836.  
  837. ULONG AllocExtMem(bytesize) - Allocates memory for expansion memory
  838. ULONG Alloc24BitMem(bytesize) - Allocates memory for expansion memory in 24 bit space
  839.  D0                 D0
  840.  
  841. Lots of games need more than the standard 512K of chip memory.
  842. They often do some tests to know where they can write (see the patch section
  843. in the guide).
  844. Sometimes it's better not to leave the game detect the expansion RAM itself.
  845. Using AllocExtMem, you'll allocate a block of 512K, 1024K or any size, and
  846. you'll keep it in mind until the game searches for memory. Patch the routine
  847. with the pointer you allocated and:
  848.  
  849. 1) You'll be sure the game uses fast memory
  850. 2) The quit option will be safe, which means the memory will not be corrupted
  851.    by the game.
  852.  
  853. You could do this allocation by hand but as you always quit by calling InGameExit(),
  854. you could not get control again to free the memory.
  855. AllocExtMem() stores the data useful for FreeMem, and InGameExit() tries to free
  856. the memory you allocated automatically.
  857.  
  858. If you select the NOFAST tooltype, the extension memory block to be returned
  859. will ALWAYS be $80000, and more chip memory will be saved when you call
  860. SaveOSData (no need to add). E.g:
  861.  
  862.         move.l        #$80000,D0
  863.         JSRABS        AllocExtMem
  864.         RELOC_MOVEL   D0,ExtBase   ; relocatable macro for move.l
  865. ...
  866. SAVE_OSDATA $80000
  867.  
  868. WARNING: Do not call this routine more than once, as the first allocated zone won't
  869. be freeable.
  870.  
  871. Alloc24BitMem is exactly the same function except that it will try to allocate memory
  872. with the 24BITDMA flag set (chip of 24 bit fastmem if you've got some). Useful for
  873. some games that don't like 32 bit fastmem (shitty coded).
  874.  
  875. Both will check that the beginning of the allocated block is above address $80000,
  876. and will return 0 if it's below.
  877.  
  878. See also: 
  879.  
  880.  
  881.  
  882.  
  883. JOTDStartup/OpenFakeExec()
  884.  
  885.  
  886. ULONG OpenFakeExec(void) - Create a exec-like function table
  887.  D0
  888.  
  889. This routine (new since V0.7 of JST) allocates $300 bytes and creates a function
  890. table that matches ExecBase offsets. Of course all calls are not emulated, and some
  891. are forbidden. For instance, you cannot OpenLibrary() (of course), or OpenDevice
  892. with device name different from "trackdisk.device".
  893.  
  894. To use only after SaveOSData. Fake ExecBase will be in $4.
  895. For the moment it does not support ExecBase structure. Only functions are supported.
  896.  
  897. This function table saves a lot of hassle because you don't have to insert BRA.B
  898. everywhere to skip those function calls.
  899.  
  900. Calls supported:
  901.  
  902. CacheClearU (flushes caches) 
  903. CacheClearE (flushes caches)
  904. CacheControl (flushes caches, returns 0 in D0 and D1)
  905. AllocAbs (returns the value in A1 in D0, as if absblock had been allocated)
  906. DoIO (calls TrackLoad(), as only trackdisk.device can be opened. Returns 0)
  907. OpenDevice (checks for "trackdisk.device", and then returns 0)
  908. FindTask (returns 0 in D0!!)
  909.  
  910. DoIO() is limited to commands 2 and 9. Write is not supported. If you want it to
  911. be, you have to overwrite the DoIO function with SetFakeFunction().
  912.  
  913. Inactivated calls:
  914.  
  915. Disable
  916. Enable
  917. Forbid
  918. Permit
  919. SuperState
  920. UserState
  921. AddPort
  922. RemPort
  923. CloseLibrary
  924. CloseDevice 
  925.  
  926. Calling any of the above will only do a RTS
  927.  
  928. Unsupported calls:
  929.  
  930. OpenLibrary
  931. OldOpenLibrary
  932. AllocMem
  933. FreeMem
  934. AvailMem
  935.  
  936. Calling unsupported calls and other calls will trigger an runtime error.
  937. The difference is that calling an unsupported call will display a specific message
  938. (AllocMem not defined...) whereas other calls are not differentiated in the error
  939. message (sorry you have to hunt for the offset)
  940.  
  941. Anyway, you can overwrite the system calls with the SetFakeFunction() call.
  942. This way, you can define your own AllocMem(), etc...
  943.  
  944. If you succeed in defining some useful and cool routines, I'll be glad to integrate
  945. them in JST default fakeexec emulation.
  946.  
  947. Return Values:
  948.  
  949. D0: 0 in any cases at the moment, but soon will return 0 if OK.
  950.  
  951. Note:
  952.  
  953. If DEADLY tooltype is on (DEADLY sets $FF000001 in ExecBase location to detect games
  954. which use system calls besides other things), OpenFakeExec will display a warning.
  955. DEADLY ExecBase kill will be deactivated.
  956.  
  957. Sometimes the game just reads in ExecBase to see the first block of fastmem, does calculations
  958. on it with ANDs #$FFF80000 and so on. In this case you have to patch the routine by hand.
  959. Just run the game from floppy or without OpenFakeExec or DEADLY to understand how it behaves,
  960. and then copy the behaviour.
  961. The best thing to do is to have a stock A500 with Action Replay. Then you can see exactly how
  962. the game understands and stores the info for 512K chip and 512K fast.
  963.  
  964.  
  965. See Also: SetFakeFunction(),TrackLoad()
  966.  
  967.  
  968.  
  969.  
  970. JOTDStartup/FreezeAll()
  971.  
  972.  
  973. void FreezeAll() - Freeze DMA and interrupts
  974.  
  975. Be sure to save the custom registers before with SaveCustomRegs.
  976. This function is useful to start/stop a game without being annoyed
  977. by ongoing DMA on interrupts.
  978.  
  979. See also: SaveCustomRegs(),RestoreCustomRegs()
  980.  
  981.  
  982.  
  983.  
  984. JOTDStartup/LoadDisks()
  985.  
  986.  
  987. void LoadDisks() - Load Disks in memory
  988.  
  989. Loads the disk from the HD_PARAMS macro parameters in the user program
  990. no parameters are returned. The routine will exit with an error message
  991. if something fails (no memory, file not found...)
  992. else, it will return to the caller.
  993.  
  994. See also: LoadFiles(), LoadDiskFromName()
  995.  
  996.  
  997.  
  998.  
  999. JOTDStartup/LoadDisksIndex()
  1000.  
  1001.  
  1002. void LoadDisksIndex(index) - Load Disks in memory, starting from index
  1003.                       D0
  1004.  
  1005. Same thing as LoadDisks(), but it begins at the disk number specified in D0
  1006.  
  1007. See also: LoadDisks(), LoadDiskFromName()
  1008.  
  1009.  
  1010.  
  1011.  
  1012. JOTDStartup/LoadDiskFromName()
  1013.  
  1014.  
  1015. void LoadDiskFromName(file name) - Load the file as a disk file
  1016. D0
  1017. Loads the disk from the HD_PARAMS macro parameters in the user program,
  1018. but the name will be ignored and replaced by the one you mention.
  1019. no parameters are returned. The routine will exit with an error message
  1020. if something fails (no memory, file not found...)
  1021. else, it will return to the caller.
  1022.  
  1023. If you call it twice, first file will be disk 0 and second will be disk 1.
  1024.  
  1025. See also: LoadDisks(), LoadFiles()
  1026.  
  1027.  
  1028.  
  1029.  
  1030. JOTDStartup/LoadSmallFiles()
  1031.  
  1032.  
  1033. void LoadSmallFiles(size_limit) - Load small files in the current directory
  1034.                       D0
  1035.                       
  1036. This function will load all the files which length is inferior to
  1037. size_limit. The other ones will be loaded during game, but it is
  1038. transparent to the programmer because the ReadFile() function will
  1039. read either from preloaded files or from hard disk if the file is
  1040. too big to have been cached.
  1041. You'll understand that you'll have to adjust properly size_limit
  1042. depending on the game you're patching. If a game directory holds
  1043. 30 files of 1000 bytes each, and some big files (>50Ko)
  1044. you should set size_limit over 1000 else the ReadFileHD will be
  1045. called very often and as OS swaps take time and blackout the display,
  1046. your loader won't use properly the HDLOAD feature.
  1047.  
  1048. NOTE: If HDLOAD is not set, this function will behave exactly as
  1049. LoadFiles(), and will read all the files (no size limit)
  1050.                       
  1051. See also: LoadDisks(), LoadFiles(), ReadFile()
  1052.  
  1053.  
  1054.  
  1055.  
  1056. JOTDStartup/LoadFiles()
  1057.  
  1058.  
  1059. void LoadFiles() - Load all the files in the current directory
  1060.  
  1061.  
  1062. This function will perform a Lock() in the current directory, then will
  1063. create the structures to store the files and read them all in memory.
  1064. It does not load subdirectories. Only flat files will be read, so be
  1065. careful with games storing data in subdirectories. The installation
  1066. procedure will have to flatten the file structure.
  1067.  
  1068. This function will exit with an error message if an error occurs
  1069. else, it will return to the caller
  1070.  
  1071. See also: LoadSmallFiles(),LoadDisks(),ReadFileFast(),LoadRNCFile().
  1072.  
  1073.  
  1074.  
  1075.  
  1076. JOTDStartup/GetFileLength()
  1077.  
  1078.  
  1079. ULONG GetFileLength(filename) - Gets the length (bytes) of a file
  1080.   D0                   D0
  1081.  
  1082. This function returns the length of a file in bytes. If the file is not found,
  1083. it will return -1, so be careful to test the value.
  1084.  
  1085. This function can only be called when the OS is active (not during game,
  1086. or if you must do so, do it within a InGameOSCall).
  1087.  
  1088. See also: ReadFile()
  1089.  
  1090.  
  1091.  
  1092.  
  1093. JOTDStartup/TestFile()
  1094.  
  1095.  
  1096. ULONG TestFile(filename) - Tests if a file exists on the hard drive
  1097.   D0               D0
  1098.  
  1099.  
  1100. This function returns 0 if the specified filename exists (relative path
  1101. from JST path)
  1102.  
  1103. See also: TestFileAbs
  1104.  
  1105.  
  1106.  
  1107.  
  1108. JOTDStartup/TestFileAbs()
  1109.  
  1110.  
  1111. ULONG TestFileAbs(filename) - Tests if a file exists on the hard drive
  1112.   D0               D0
  1113.  
  1114.  
  1115. This function returns 0 if the specified filename exists (absolute path)
  1116.  
  1117. See also: TestFileAbs
  1118.  
  1119.  
  1120.  
  1121.  
  1122. JOTDStartup/LoadRNCFile()
  1123.  
  1124.  
  1125. ULONG LoadRNCFile(filename) - Loads and decrunches a RNC file from the Hard Drive.
  1126.  D0/A0/D1            D0
  1127.  
  1128. This function loads a file and decrunches it, allocating memory at the same time for the
  1129. decrunched length.
  1130. Return values: D0: error flag (0 if OK)
  1131.                A0: beginning of allocated buffer
  1132.                D1: allocated length (useful if the file space must be freed with FreeMem())
  1133.  
  1134. See also - RNCDecrunch(), RNCLength()
  1135.  
  1136.  
  1137.  
  1138.  
  1139. JOTDStartup/TransfRoutines()
  1140.  
  1141.  
  1142. void TransfRoutines(void) - (obsolete)
  1143.  
  1144. This routine is obsolete and provided only for compatibility reasons.
  1145. It does strictly nothing.
  1146.  
  1147. See also: 
  1148.  
  1149.  
  1150.  
  1151.  
  1152. JOTDStartup/BlockFastMem()
  1153.  
  1154.  
  1155. void BlockFastMem(sparemem) - Blocks fastmem
  1156.                       D0
  1157.  
  1158. D0 is the number of bytes to leave unallocated (roughly, not accurate).
  1159. 0 in D0 means the routine will try to allocate all fast memory available.
  1160.  
  1161. This is useful for some games which want chipmem but forget to specify it
  1162. in AllocMem() (old games), and also for games which do not like memory
  1163. located over $FFFFFF (coded in 32 bits).
  1164.  
  1165. Do not use it if not necessary (impossible to return to the OS
  1166. after that). You can use it when the TUDE NOFASTMEMORY BOOT=HIGHCHIP
  1167. is necessary to boot the wanted game from floppy without problems
  1168. TUDE is copyright N.O.M.A.D 1995. It can be found on aminet.
  1169.  
  1170. Normally if you track the game memory allocation, you should not use this
  1171. routine. Force the game to allocate its extension memory block in chipmem
  1172. (provided you've got 1MB chip, see BodyBlows patch).
  1173.  
  1174. See also: Degrade(), DegradeCpu().
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180. JOTDStartup/Degrade()
  1181.  
  1182.  
  1183. void Degrade(cacheset,cachemask) - Degrades everything to run games properly
  1184.                 D0       D1
  1185.  
  1186. This routine is a combination of both DegradeCpu() and DegradeGfx() routines.
  1187. Call it just before saving OS data and booting the game.
  1188.  
  1189. A classic sequence is:
  1190.  
  1191. moveq #0,D0
  1192. move.l #CACRF_CopyBack,D1
  1193. JSRABS Degrade ; leave only instruction cache
  1194. GO_SUPERVISOR
  1195. SAVE_OSDATA $80000
  1196. .. boot stuff
  1197. See also: BlockFastMem(), DegradeCpu(), DegradeGfx(), Enhance()
  1198.  
  1199.  
  1200.  
  1201.  
  1202. JOTDStartup/Enhance()
  1203.  
  1204.  
  1205. Resets system enhancements (VBR, caches, gfx...)
  1206.  
  1207. This function should *NEVER* be called when using the library, but it could be
  1208. useful to call it to see what happens in an OS swap that fails. It's a function
  1209. that can be used in the standalone degrade code I've written
  1210.  
  1211. See also: Degrade()
  1212.  
  1213.  
  1214.  
  1215.  
  1216. JOTDStartup/DegradeGfx()
  1217.  
  1218.  
  1219. void DegradeGfx() - Degrades graphics to run games properly
  1220.  
  1221. This routine degrades the display using LoadView(NULL), and can set PAL or NTSC (tooltype).
  1222. It also opens an intuition screen if possible.
  1223.  
  1224.  
  1225. See also: BlockFastMem(), DegradeCpu(), Degrade()
  1226.  
  1227.  
  1228.  
  1229.  
  1230. JOTDStartup/DegradeCpu()
  1231.  
  1232.  
  1233. DegradeCpu(cacheset,cachemask) - Degrades only cpu related hardware
  1234.                 D0       D1
  1235.  
  1236. This routine does the following:
  1237.  
  1238. - It sets the VBR to $0 for 68010 and higher cpus unless the LEAVEVBR tooltype is present.
  1239. - It removes the specific 68060 caches (branch, writeallocate, and also the data/copyback
  1240.   cache, this last one the CacheControl() function leaves alone, even if you want to disable
  1241.   CopyBack)
  1242. - If NOCACHES is activated in the tooltypes, it will disable ALL caches.
  1243.  
  1244. The cacheset and cachemask variables are the same as in exec CacheControl().
  1245. Refer to the CacheControl autodoc for more details.
  1246.  
  1247. This function does not affect graphics modes at all.
  1248.  
  1249. See also: Degrade(), DegradeGfx()
  1250.  
  1251.  
  1252.  
  1253.  
  1254. JOTDStartup/Display()
  1255.  
  1256.  
  1257. void Display(message pointer) - Displays a message in the opened console or CLI
  1258.                A1
  1259.  
  1260. This function is generally called from the Mac_printf macro. This is more convenient,
  1261. but we may need to call it directly in some special cases.
  1262. If the program has been run from CLI, Display() will write in the CLI. If run from
  1263. workbench, it will write in the window opened by the startup program (see HD_PARAMS macro).
  1264.  
  1265. If no window exists, this function will do nothing (it won't even crash).
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271. JOTDStartup/CloseAllQuiet()
  1272.  
  1273.  
  1274. void CloseAllQuiet(void) - Frees everything and exits
  1275.  
  1276.  
  1277. This function frees all the memory allocated by the program (diskfiles, files, relocatable
  1278. code, windows) and quits the program. If you allocated memory from the user program
  1279. by using directly Exec routines, you'll have to free it before calling this function.
  1280. This function cannot be called when the game is running (the OS is killed). Call InGameExit
  1281. instead.
  1282. This function will exit at once, and the window will be closed if the program was started
  1283. from Workbench.
  1284.  
  1285. See also: InGameExit(), CloseAllQuiet()
  1286.  
  1287.  
  1288.  
  1289.  
  1290. JOTDStartup/CloseAll()
  1291.  
  1292.  
  1293. void CloseAll(void) - Frees everything and exits because of an error
  1294.  
  1295.  
  1296. This function frees all the memory allocated by the program (diskfiles, files, relocatable
  1297. code, windows) and quits the program. If you allocated memory from the user program, you'll
  1298. have to free it before calling this function.
  1299. This function cannot be called when the game is running (the OS is killed). Call InGameExit
  1300. instead.
  1301.  
  1302. If the program has been run from workbench, it will ask for the RETURN key before closing
  1303. the console, in order for you to see what went wrong.
  1304.  
  1305. See also: InGameExit(), CloseAllQuiet()
  1306.  
  1307.  
  1308.  
  1309.  
  1310. JOTDStartup/FlushCachesSys()
  1311.  
  1312.  
  1313. void FlushCachesSys(void) - Flushes the caches using OS calls
  1314.  
  1315. Well, this function calls CacheControl(0L,0L), and the caches are flushed.
  1316.  
  1317. See also: FlushCachesHard(),Degrade()
  1318.  
  1319.  
  1320.  
  1321.  
  1322. JOTDStartup/GetMemFlag()
  1323.  
  1324.  
  1325. ULONG GetMemFlag(void) - Return MEMF_REVERSE if kick 39+
  1326.  D1
  1327.  
  1328. As the MEMF_REVERSE flag (AllocMem, AllocVec) does not exist in KS 1.x, and was broken
  1329. until V39, this function checks for the kick version, and returns 0 if it is too old.
  1330. Else, it will return MEMF_REVERSE.
  1331.  
  1332. That will explain that JST loaders will have more chances to work on V39 machines.
  1333.  
  1334.  
  1335.  
  1336.  
  1337. JOTDStartup/TestxMbChip()
  1338.  
  1339.  
  1340. ULONG Test1MBChip() - Hardware test for 1MB chip memory
  1341. ULONG Test2MBChip() - Hardware test for 2MB chip memory
  1342.  
  1343. This routine Test1MBChip (resp Test2MBChip) pokes in the location $80000 (resp $100000),
  1344. then checks for location $0. If they are the same, then chipmem is 512K
  1345. (resp 1024K or 512K) ,else, it's at least 1024K (resp 2048K)
  1346. This routine is safe. It calls Disable and restores the altered chip locations.
  1347. Returns 0 if chipmem is as required (>1024K resp 2048K), -1 else.
  1348.  
  1349. NOTE: To test for 512K chip, use Test1MBChip. To check for 1MB chip, use
  1350. Test1MBChip, then Test2MBChip to know if it's only 1024K or 2048K.
  1351. I don't think further amigas (if there any) will have more than 2MB of chipmem...
  1352. Also notice that some computers have 2MB of chipmem and are not AGA, and
  1353. that some so-called AGA games only assume you've got 2MB of chip and can
  1354. be run on 2MB chip ECS amigas or even on 512K OCS amigas (but in that last
  1355. case you'll have to relocate some code heavily!!)
  1356.  
  1357. Example: Jungle Strike AGA (Ocean) runs fine on UAE with 2MB of chipmem.
  1358.  
  1359.  
  1360. See also: CheckAGA()
  1361.  
  1362.  
  1363.  
  1364.  
  1365. JOTDStartup/CheckAGA()
  1366.  
  1367.  
  1368. ULONG CheckAGA(void) - Checks DeniseID to see if the computer supports AGA or not
  1369.   D0
  1370.  
  1371. This function will return 0.L in D0 if AGA is supported, -1.L else.
  1372.  
  1373.  
  1374.  
  1375.  
  1376. JOTDStartup/GetSR()
  1377.  
  1378.  
  1379. UWORD   GetSR() - Returns CPU status register
  1380.  D0          
  1381.                   
  1382. SR will be copied in D0. No need to be in suprevisor mode to call
  1383. this function (or else it has no interest).
  1384.  
  1385. See also:
  1386.  
  1387.  
  1388.  
  1389.  
  1390. JOTDStartup/GetAttnFlags()
  1391.  
  1392.  
  1393. UWORD   GetAttnFlags() - Returns CPU AttnFlags while OS is down
  1394.  D0          
  1395.                   
  1396. At startup, exec's AttnFlags is copied and relocated. So if you need
  1397. to know something about the CPU you patch is running on, use this
  1398. function. You can test the bits like a normal CPU bit test.
  1399.  
  1400. See also:
  1401.  
  1402.  
  1403.  
  1404.  
  1405. JOTDStartup/WriteFileHD()
  1406.  
  1407.  
  1408.        WriteFileHD(command,length,name,buffer) - Writes a file to disk during game
  1409. D0,D1                D0(=0)   D1    A0    A1
  1410.                   
  1411. This function is very useful to write some data from disk on demand during
  1412. the game for savegame data files or hiscores.
  1413.  
  1414. D0.L: command: leave to 0 for the moment
  1415. D1.L: length in bytes (be careful!!)
  1416. A0:   pointer on the name, NULL terminated
  1417. A1:   source data buffer (either in fastmem or chipmem)
  1418.  
  1419.  
  1420. Note: as the game chipmem is transfered to a fastmem area during OS calls,
  1421. if you load a file into a chipmem zone, it will be loaded in the fastmem
  1422. mirror instead, and will appear in chipmem after the OS is killed again,
  1423. so don't worry about that (except if you save 2MB chip and activate memsave).
  1424.  
  1425. The function returns D0=0 on success, -1 else.
  1426. If success, D1.L contains the length actually written.
  1427.  
  1428.  
  1429. You can call this function whether the OS is alive or not.
  1430.  
  1431.  
  1432. If you want to write user data (like scores or gamesaves), you'd better use WriteUserFileHD()
  1433. because this function uses SAVEDIR parameter to write data to another directory in the
  1434. registered version of JST.
  1435.  
  1436. See also: InGameOSCall(), WriteUserFileHD().
  1437.  
  1438.  
  1439.  
  1440. JOTDStartup/WriteUserFileHD()
  1441.  
  1442.  
  1443.        WriteUserFileHD(command,length,name,buffer) - Writes a file to disk during game in SAVEDIR
  1444. D0,D1                   D0(=0)   D1    A0    A1
  1445.  
  1446.  
  1447. Same thing as WriteFileHD, except that if SAVEDIR tooltype is set, (SAVEDIR-RAM:), the data
  1448. will be saved here, and not in the game directory. Useful for write only/copyback cached
  1449. partitions.
  1450.  
  1451. See also: WriteFileHD(), ReadUserFileHD().
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457. JOTDStartup/ReadUserFileHD()
  1458.  
  1459.  
  1460.        ReadUserFileHD(command,length,name,buffer) - Reads a file to disk during game in SAVEDIR
  1461. D0,D1                  D0(=0)   D1    A0    A1
  1462.  
  1463.  
  1464. Same thing as ReadFileHD, except that if SAVEDIR tooltype is set, (SAVEDIR-RAM:), the data
  1465. will be saved here, and not in the game directory.
  1466.  
  1467. See also: ReadFileHD(), WriteUserFileHD().
  1468.  
  1469.  
  1470.  
  1471.  
  1472. JOTDStartup/ReadFile()
  1473.  
  1474.  
  1475.       ReadFile(command,length,name,buffer) - Reads a file from disk/RAM during game
  1476. D0,D1           D0(=0)   D1    A0    A1
  1477.  
  1478. This command is very similar to ReadFileHD() except that it will
  1479. check if the file was not cached in memory first.
  1480.  
  1481. In the case HDLOAD/LOWMEM is on, it will often read files from HD. If those flags are off,
  1482. all the files will be loaded from memory because they had been preloaded
  1483. (by LoadFiles() or LoadSmallFiles()).
  1484.  
  1485. See also: ReadFileHD(),ReadFilePart().
  1486.  
  1487.  
  1488.  
  1489.  
  1490. JOTDStartup/ReadFilePart()
  1491.  
  1492.  
  1493.       ReadFilePart(command,length,offset,name,buffer) - Reads a part of a file from disk/RAM during game
  1494. D0,D1               D0(=0)   D1     D2    A0    A1
  1495.  
  1496. This command is very similar to ReadFilePartHD() except that it will
  1497. check if the file was not cached in memory first.
  1498.  
  1499. In the case HDLOAD/LOWMEM is on, it will often read files from HD. If those flags are off,
  1500. all the files will be loaded from memory because they had been preloaded
  1501. (by LoadFiles() or LoadSmallFiles()).
  1502.  
  1503. See also: ReadFileHD(),ReadFilePartHD().
  1504.  
  1505.  
  1506.  
  1507.  
  1508. JOTDStartup/ReadFilePartHD()
  1509.  
  1510.  
  1511.       ReadFilePartHD(command,length,offset,name,buffer) - Reads a part of a file from disk/RAM during game
  1512. D0,D1                 D0(=0)   D1     D2    A0    A1
  1513.  
  1514. This function will try to load a part of a file from HD.
  1515.  
  1516. D0: 0 if OK
  1517. D1: length read in bytes
  1518.  
  1519. See also: ReadFileHD(),ReadFilePart().
  1520.  
  1521.  
  1522.  
  1523.  
  1524. JOTDStartup/ReadFileHD()
  1525.  
  1526.  
  1527.       ReadFileHD(command,length,name,buffer) - Reads a file from disk during game
  1528. D0,D1             D0       D1    A0    A1
  1529.                   
  1530. This function is very useful to read some data from disk on demand during
  1531. the game. It can load the game files or savegame data files.
  1532.  
  1533. D0: command: 0: normal operation, $FF reserved. Leave to zero at the moment
  1534. D1: length in bytes. -1 means all the file
  1535. A0: pointer on the name, NULL terminated
  1536. A1: destination data buffer (either in fastmem or chipmem)
  1537.  
  1538. Note: as the game chipmem is transfered to a fastmem area during OS calls,
  1539. if you load a file into a chipmem zone, it will be loaded in the fastmem
  1540. mirror instead, and will appear in chipmem after the OS is killed again,
  1541. so don't worry about that (except if you save 2MB chip, in that case,
  1542. I allocate chipmem to save some fastmem, so there's a gap!!)
  1543.  
  1544. The function returns D0=0 on success, -1 else.
  1545. If success, D1.L contains the length actually read.
  1546.  
  1547. You can call this function whether the OS is alive or not.
  1548.  
  1549. This function will not check for cached file in memory. Calling ReadFileHD forces
  1550. a read from HD (an OS swap is necessary). If you don't know if the file was cached or
  1551. not, use ReadFile() instead.
  1552.  
  1553. If you want to read user data (like scores or gamesaves), you'd better use ReadUserFileHD()
  1554. because this function uses SAVEDIR parameter to read data from another directory in the
  1555. registered version of JST.
  1556.  
  1557. See also: ReadFile(), InGameOSCall(), WriteFileHD(), DeleteFileHD(), ReadUserFileHD().
  1558.  
  1559.  
  1560.  
  1561.  
  1562. JOTDStartup/DeleteFileHD()
  1563.  
  1564.  
  1565. ULONG DeleteFileHD(name) - Deletes a file from disk during game
  1566.  D0                 A0
  1567.  
  1568. This can also be done by calling InGameOSCall() but I needed it in the
  1569. Sensible Golf patch and then I included this function in the library.
  1570.  
  1571. Will return 0 if success, -1 else.
  1572.  
  1573. You can call this function whether the OS is alive or not.
  1574.  
  1575. If you want to delete user data (like scores or gamesaves), you'd better use DeleteUserFileHD()
  1576. because this function uses SAVEDIR parameter to delete data from another directory in the
  1577. registered version of JST.
  1578.  
  1579. See also: InGameOSCall(), ReadFileHD(), WriteFileHD(), DeleteUserFileHD()
  1580.  
  1581.  
  1582.  
  1583.  
  1584. JOTDStartup/DeleteUserFileHD()
  1585.  
  1586.  
  1587. ULONG DeleteUserFileHD(name) - Deletes a file from disk during game in SAVEDIR
  1588.  D0                     A0
  1589.  
  1590. Same routine as DeleteFileHD(), but uses SAVEDIR if set to search file to delete
  1591. into. Unvaluable because cannot be reproduced using InGameOSCall() (because
  1592. for the moment it's not possible to get SAVEDIR value from the object)
  1593.  
  1594.  
  1595. See also: InGameOSCall(), ReadFileHD(), WriteFileHD(), DeleteUserFileHD()
  1596.  
  1597.  
  1598.  
  1599.  
  1600. JOTDStartup/InGameOSCall()
  1601.  
  1602.  
  1603. ULONG InGameOSCall(entrypoint) - Calls a routine containing OS code
  1604.                        A4
  1605.  
  1606. This is one of the most powerful and also one of the most dangerous function of
  1607. this package.
  1608. It allows the user to call a program using normal system calls, while the game
  1609. has totally destroyed the OS.
  1610. It restores the OS and interrupts and saves the game memory, goes in user mode, calls
  1611. the user routine, and restores everything for the game.
  1612. The display goes black because this is not possible to save the colormap and other
  1613. screen data.
  1614. The user routine can trash all the registers. They're saved and restored after the call.
  1615.  
  1616. However, there are problems with this routine:
  1617.  
  1618. - Any Write() made to disk may not terminate when the game is re-activated. So
  1619.   you'll better disable disk caches and quit the game correctly after that.
  1620.   If someone knows how to wait for the disk activity to finish, please call me.
  1621.   The problem that may occur is a devalidation of the disk (not very important).
  1622.   I use the dos Delay() command after the write operation with 2 seconds, and it works:
  1623.  
  1624. move.l #100,D1
  1625. move.l _DosBase(pc),A6
  1626. JSRLIB Delay
  1627.  
  1628. - Playing with the keyboard while the disk is writing or reading locks the system.
  1629.   I don't know where it comes from, but I'll find out. For the moment, avoid to press
  1630.   any key during disk accesses (especially writes, this can lead to write errors !!!)
  1631.  
  1632. Besides those problems this routine is the only way to make real hard disk versions of games
  1633. which load and save data to disk.
  1634. Lots of the patches I've written use this routine. It took me some time for it to be reliable.
  1635. Some users still have problems. I'm improving it from time to time.
  1636.  
  1637.  
  1638. This routine returns 0 when the routine has been called, and -1 if the routine has not been
  1639. called because of the impossibility to save/restore the operating system, so be careful for
  1640. users without too much memory...
  1641.  
  1642. The register D0 you'll set in the OS routine will be passed to your program. It must be coherent
  1643. with the error code. E.g: if everything is OK, return 0, else return -1, or -2 to make a difference
  1644. with the OS switching error.
  1645.  
  1646. Example:
  1647.  
  1648. LoadScoreFile:
  1649. lea scorename(pc),A0
  1650. move.l A0,D1
  1651. move.l #MODE_OLDFILE,D2
  1652. move.l _SysBase(pc),A6
  1653. JSRLIB Open
  1654. tst.l D0
  1655. beq error$
  1656.  
  1657. ... ; do our stuff (reading...)
  1658.  
  1659. JSRLIB Close
  1660. moveq.l #0,D0
  1661. rts
  1662. error$
  1663. moveq.l #-2,D0 ; file error code
  1664. rts
  1665.  
  1666. LoadHighscores:
  1667. lea LoadScoreFile(pc),A4
  1668. JSRGEN InGameOSCall
  1669. tst.l D0
  1670. beq ok$ ; all is OK
  1671. cmp.l #-1,D0
  1672. beq oserr$ ; os could not be restored
  1673. ; else file error
  1674.  
  1675. I recently added the ReadFileHD() and WriteFileHD() routines, and this
  1676. routine is not to be used in most cases, but sometimes it's compulsory
  1677. (for instance listing a savegame directory during the game (Cannon Fodder 2))
  1678.  
  1679.  
  1680. IMPORTANT: This function will do nothing if the NOOSSWAP tooltype/argument is activated. To check
  1681. this argument, the register D1 will be set (-1.L) when _loader is called (beginning of the user
  1682. code).
  1683.  
  1684. See also: ReadFileHD(), WriteFileHD(), DeleteFileHD(), InGameExit()
  1685.  
  1686.  
  1687.  
  1688.  
  1689. JOTDStartup/PatchExceptions()
  1690.  
  1691.  
  1692. void PatchExceptions(void) - redirect system exceptions to custom routines
  1693.  
  1694.  
  1695. This routine allows to trap the following processor exceptions:
  1696.  
  1697. - Bus error
  1698. - Address error
  1699. - Illegal instruction
  1700. - Division by zero
  1701. - LINEA emulation
  1702. - LINEF emulation
  1703. - Format error
  1704. - some others... (subject to change)
  1705.  
  1706. PatchExceptions() is called at startup, so there's no need to do it by hand
  1707. normally, but it may be necessary to call it again in the user program in the
  1708. case of the game overwriting the values, and then crashes. That's why this function
  1709. is callable from user program.
  1710.  
  1711. When an exception is encountered, the handler returns to the OS with the 'exception
  1712. occured' or 'linef/movep (060)' message. If you want more information, use the DEBUG
  1713. tooltype or argument when running the loader, and a memory image of the game,
  1714. the registers an some other information will be written to disk. With the memory
  1715. and the stack value, maybe you're able to track the error or find out problems using
  1716. memory dump.
  1717.  
  1718. See Also:
  1719.  
  1720.  
  1721.  
  1722.  
  1723. JOTDStartup/FlushCachesHard()
  1724.  
  1725.  
  1726. void FlushCachesHard(void) - Flushes the caches
  1727.  
  1728. This routine is *VERY* useful to flush the caches when the OS is overridden
  1729. by the game, and you still want to use fast memory with the caches on.
  1730. It addresses CACR register to invalidate instruction and data caches,
  1731. and it also calls CPUSH to flush the copyback data cache into memory
  1732. (for 68040/68060) caches.
  1733.  
  1734.  
  1735. NOTE: As long as the OS is alive, use FlushCachesSys() whenever possible.
  1736.  
  1737. See also: FlushCachesSys()
  1738.  
  1739.  
  1740.  
  1741.  
  1742. JOTDStartup/GoECS()
  1743.  
  1744.  
  1745. void GoECS(void) - degrades display and sprites to ECS
  1746.  
  1747. This function is very useful when you start the loader from a multiscan screen with
  1748. a hires pointer. In that case, if the game uses sprites, they all appear shrinked,
  1749. as the game did not switch in lores pointer. 
  1750. It modifies the value of FMODE (set to 0) and BPLCON3 (set to $0C20).
  1751. This acts also on dual playfield parameters.
  1752.  
  1753. NOTE: This function will have no effect if the system copperlists are still active,
  1754. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1755. Look at the examples provided.
  1756.  
  1757. GoECS() is just a call to ResetDisplay() followed by a call to ResetSprites().
  1758.  
  1759. See also: ResetDisplay(), ResetSprites()
  1760.  
  1761.  
  1762.  
  1763.  
  1764. JOTDStartup/ResetDisplay()
  1765.  
  1766.  
  1767. void ResetDisplay(void) - Resets 15KHz display
  1768.  
  1769. This function avoids to get a modulo/AGA display problem.
  1770.  
  1771. NOTE: This function will have no effect if the system copperlists are still active,
  1772. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1773. Look at the examples provided.
  1774.  
  1775. See also: GoECS(), ResetSprites()
  1776.  
  1777.  
  1778.  
  1779.  
  1780. JOTDStartup/ResetSprites()
  1781.  
  1782.  
  1783. void ResetSprites(void) - Resets LORES sprites
  1784.  
  1785.  
  1786. If the sprites are too small vertically, call this function.
  1787.  
  1788. NOTE: This function will have no effect if the system copperlists are still active,
  1789. as they reset BPLCON3 every screen scan. Use it in an early stage of the game loader.
  1790. Look at the examples provided.
  1791.  
  1792. See also: GoECS(), ResetDisplay()
  1793.  
  1794.  
  1795.  
  1796.  
  1797. JOTDStartup/KickVerTest()
  1798.  
  1799.  
  1800. ULONG KickVerTest(kickversion) - Test if ROM version is newer than a given version
  1801.  D0                    D0
  1802.  
  1803. KickVerTest() uses the SoftVer variable in the ExecBase structure to test the
  1804. kickstart version.
  1805.  
  1806. kickversion is the kickstart version number (for instance 35,36,39...)
  1807. The function will return 0 is the installed version is newer than the wanted version
  1808. and -1 if not.
  1809.  
  1810. See also: Kick37Test()
  1811.  
  1812.  
  1813.  
  1814.  
  1815. JOTDStartup/Kick37Test()
  1816.  
  1817.  
  1818. ULONG Kick37Test(void) - Test if ROM is V37 or newer
  1819.  D0
  1820.  
  1821. The same thing as KickVerTest(), but compares the version to V37 (matches Workbench 2.0).
  1822. Useful when you don't know if you can use 2.0 features.
  1823.  
  1824. Returns D0=0  if KS>36, D0!=0 if KS<=36
  1825.  
  1826. See also: KickVerTest()
  1827.  
  1828.  
  1829.  
  1830.  
  1831. JOTDStartup/InitTrackDisk()
  1832.  
  1833.  
  1834. void InitTrackDisk(void) - Initialize trackdisk.device emulation
  1835.  
  1836. Call this when you need to emulate a DoIO(), very frequent in the bootblock of
  1837. games, which use trackdisk.device to load their loading routines, then forget
  1838. it along with the remainder of the system.
  1839. When you re-source the bootblock, replace all the JSRLIB DoIO by JSRGEN TrackLoadFast.
  1840. Before jumping to the bootblock code, you MUST call InitTrackDisk (use JSRGEN too),
  1841. or else the loads will be done anywhere in the memory -> GURU.
  1842. Refer to the examples for more details.
  1843.  
  1844. See also: TrackLoadFast(),SetTDUnit(),ReadRobSectorsFast()
  1845.  
  1846.  
  1847.  
  1848.  
  1849. JOTDStartup/TrackLoad
  1850.  
  1851.  
  1852. void TrackLoad(void) - Replaces DoIO function to read from a virtual floppy
  1853.  
  1854. This function replaces TrackLoadFast. It has the same function, but is able to
  1855. read from HD when LOWMEM is activated.
  1856.  
  1857. This function replaces the DoIO() function in the case of a floppy disk.
  1858. Once initialized with InitTrackDisk() and possibly with SetTDUnit(), you are
  1859. able to read sectors from the virtual floppy device exactly with the trackdisk.device
  1860. (only read is supported. There is no write mode).
  1861.  
  1862. See also: InitTrackDisk(),SetTDUnit(),ReadRobSectors()
  1863.  
  1864.  
  1865.  
  1866.  
  1867. JOTDStartup/SetTDUnit()
  1868.  
  1869.  
  1870. void SetTDUnit(unit) - Sets trackdisk.device emulation unit
  1871.                D0
  1872.  
  1873. This function allows to change the current virtual drive (actually it changes disks).
  1874. Use it in conjunction with TrackLoadFast(). It has no effect with ReadRobSectorsFast().
  1875.  
  1876. The unit is not limited to 3, as you can patch games which have got 4 floppies or more.
  1877.  
  1878. If this routine is not called, the unit will be 0 (default, useful for bootblocks).
  1879.  
  1880. See also: InitTrackDisk(),TrackLoad()
  1881.  
  1882.  
  1883.  
  1884.  
  1885. JOTDStartup/ReadFileFast()
  1886.  
  1887.  
  1888. ULONG ReadFileFast(filename,buffer,command,length) - Transfer a file in the given buffer
  1889.  D0                  A0      A1      D0      D1
  1890.  
  1891. Uses the Rob Northern file interface.
  1892.  
  1893. used in:
  1894.  
  1895. Cannon Fodder 2, Darkmere, Sensible Golf, Sensible Soccer, Road Rash...
  1896.  
  1897. Different versions may exist: D1 can be meaningless. In this case, set it to -1.
  1898. Some games only use commands 0 and 5
  1899.  
  1900. Darkmere uses 0, 5, 6, 7, 8 extensively.
  1901.  
  1902. in:
  1903. A0: Filename
  1904. A1: Buffer
  1905. D0: command:
  1906. D1: misc
  1907.  
  1908. D0:
  1909.  
  1910. 0: Read
  1911. in : D1: # bytes (-1: all), A0: filename, A1: buffer
  1912. out: D0: 0 if OK,  D1: length read
  1913.  
  1914. 1: Write (disabled)
  1915. in: D1: # bytes          , A0: filename, A1: buffer
  1916. out: D0: 0 if OK,  D1: length written
  1917.  
  1918. 2: Never seen it before ????
  1919. 3: Read directory (disabled)                        A0: 
  1920. 4: Format floppy (disabled)
  1921. 5: Get Length
  1922. in : A0: filename
  1923. out: D0: 1 if found, 0 else, D1: length
  1924.  
  1925. 6: Nothing (I think)
  1926.  
  1927. 7: Read last file w/ offset
  1928. in : D1: # bytes          , A0: scratch  ,A1: buffer
  1929. out: D0: ???
  1930.  
  1931. 8: Set offset on last accessed file
  1932. in : D1: offset           , A0: scratch  ,A1: scratch
  1933. out: D0: offset
  1934.  
  1935. In order to use this function, you must initialize the fastfile structure by calling
  1936. LoadFiles(), else this will fail.
  1937.  
  1938. filename: a NULL-terminated string
  1939. buffer: a pointer on a memory zone
  1940. length: the length in bytes. If you pass -1, the whole file will be read.
  1941.  
  1942. Sometimes, the games use this routine as-is, and you've got only to patch.
  1943. However, you've got to check for files which are not found: they can be savegames loads.
  1944.  
  1945. In that case, you can call the original routine (read from floppy) or make a HD access
  1946. using InGameOSCall() (much harder, provided you've got to read the directory)
  1947.  
  1948.  
  1949. To read part of files (using the 7 and 8 commands), it's better to use ReadFilePart()
  1950.  because the interface is more natural. However, this routine can be used as-is in some
  1951. games (such as Darkmere, which uses the 7 and 8 commands, and took me a while to figure
  1952. it out!)
  1953.  
  1954.  
  1955. See also: LoadFiles(),ReadFile(),ReadFilePart()
  1956.  
  1957.  
  1958.  
  1959.  
  1960. JOTDStartup/ReadRobSectors()
  1961.  
  1962.  
  1963. ULONG ReadRobSectors(drivenum,offset,blocks,command,buffer) - Reads sectors from virtual disk
  1964.  D0                    D0      D1     D2     D3      A0
  1965.  
  1966.  
  1967. This is the main all-purpose loading routine of the package. I chose this syntax
  1968. because this routine is used as-is in lots of games and can be used provided
  1969. an offset correction or a disk choice is done in many games.
  1970. I noticed it and replaced it in:
  1971.  
  1972. Assassin, BodyBlows, AlienBreed, Warzone, Magic Pockets, Cadaver,
  1973. Chaos Engine, Cannon Fodder 2, Project-X, Mortal Kombat I & II,
  1974. Gods, Rodland, Desert Strike, Qwak, and others...
  1975.  
  1976. INTERFACE:
  1977.  
  1978. drivenum/D0 = Drive Number - sometimes matches disk number
  1979. offset/D1   = Offset in bytes / 512 (also offset in sectors)
  1980. block/D2    = nb of 512 bytes sectors to read
  1981. command/D3  = 0: Read data, !=0 Writes (has to be done manually, as it's better to create a separate file for game saves)
  1982. buffer/A0   = Start address
  1983.  
  1984. For 2 disked games using DF0: and DF1:, you generally don't have to worry about disk changes,
  1985. as disk1 is supposed to be in DF0: and disk2 in DF1:, so D0 will be set in a correct way and
  1986. the game will read from the correct disk anyway.
  1987.  
  1988. See the examples to understand fully the interest of this routine.
  1989.  
  1990. Specifying the LOWMEM tooltype/argument at startup causes this
  1991. routine to read the data from the file instead of the cached images
  1992. in memory (which will not exist if LOWMEM is activated).
  1993.  
  1994. See also: TrackLoadFast(), LoadDisks(), ReadDiskPart()
  1995.  
  1996.  
  1997.  
  1998.  
  1999. JOTDStartup/ReadDiskPart()
  2000.  
  2001.  
  2002. ULONG ReadDiskPart(drivenum,length,offset,buffer) - Reads bytes from virtual disk
  2003.  D0                   D0      D1     D2     A0
  2004.  
  2005.  
  2006. Even if the Rob Northen format is widespread, this routine is the alternative.
  2007. It is able to read any number of bytes and at any location on a disk image. It's useful
  2008. for disk loaders which use a non $200 round interface.
  2009.  
  2010.  
  2011. INTERFACE:
  2012.  
  2013. drivenum/D0 = Drive Number - sometimes matches disk number
  2014. offset/D1   = Length in bytes to read
  2015. block/D2    = Offset in bytes from where to read
  2016. buffer/A0   = Start address
  2017.  
  2018. Specifying the LOWMEM tooltype/argument at startup causes this
  2019. routine to read the data from the file instead of the cached images
  2020. in memory (which will not exist if LOWMEM is activated).
  2021.  
  2022. See also: TrackLoadFast(), LoadDisks(), ReadRobSectors()
  2023.  
  2024.  
  2025.  
  2026.  
  2027. JOTDStartup/StrcpyAsm()
  2028.  
  2029.  
  2030. void StrcpyAsm(string1,string2) - Copies string
  2031.                  D0      D1
  2032.                  
  2033. Copies the string pointed by D0 to the buffer area in D1.
  2034. The source string must be NULL terminated.
  2035.  
  2036. See also: StrcmpAsm(), StrlenAsm(), ToUpper()
  2037.  
  2038.  
  2039.  
  2040.  
  2041. JOTDStartup/StrcmpAsm()
  2042.  
  2043.  
  2044. LONG StrcmpAsm(string1,string2) - Compares 2 strings (not case sensitive)
  2045.  D0              D0      D1
  2046.  
  2047. StrcmpAsm returns 0 if the 2 strings are the same (no case sensitivity,
  2048. e.g. LoA-Der is the same as LOa-deR), and -1 if they're different
  2049.  
  2050. See also: StrcmpAsm(), StrcpyAsm(), ToUpper()
  2051.  
  2052.  
  2053.  
  2054.  
  2055. JOTDStartup/StrlenAsm()
  2056.  
  2057.  
  2058. ULONG StrlenAsm(string) - Returns the length of a NULL-terminated string
  2059.  D0               D0
  2060.  
  2061.  
  2062.  
  2063.  
  2064. JOTDStartup/ToUpperAsm()
  2065.  
  2066.  
  2067. void ToUpperAsm(string) - Converts a string in upper case
  2068.  D0               D0
  2069.  
  2070.  
  2071.  
  2072.  
  2073. JOTDStartup/HexReplaceLong()
  2074.  
  2075.  
  2076. void HexReplaceLong(searched,replacer,start,end) - Searches a longword and replaces it
  2077.                        D0       D1     A0   A1
  2078.  
  2079. Designed for automatic search/replace of data/code.
  2080.  
  2081. This function can be useful to search blitter commands (move.w Dx,($58,Ax)) to patch
  2082. them with WaitBlit. For example, I'd like to insert blitterwaits in the zone
  2083. $1000-$5000 for the instruction  move.w  D1,($58,A2) (hex: $35410058)
  2084.  
  2085.     ...
  2086.     move.l   #$35410058,D0
  2087.     move.l   #$4EB800C6,D1   ; JSR ($C6).W
  2088.     lea      $1000.W,A0
  2089.     lea      $5000.W,A1
  2090.     JSRGEN   HexReplaceLong
  2091.     PATCHUSRJMP    $C6.W,DoBlit_D1A2
  2092.     ...
  2093.  
  2094. DoBlit_D1A2:
  2095.     JSRGEN   WaitBlit        ; wait blitter operations to complete
  2096.     move.w   D1,($58,A2)     ; start the blit
  2097.     rts
  2098.  
  2099. The search will be done word by word (2 bytes). Odd occurences will not be found.
  2100.  
  2101. See also: HexReplaceWord
  2102.  
  2103.  
  2104.  
  2105.  
  2106. JOTDStartup/HexReplaceWord()
  2107.  
  2108.  
  2109. void HexReplaceWord(searched,replacer,start,end) - Searches a word and replaces it
  2110.                       D0.W    D1.W     A0    A1
  2111.  
  2112. Designed for automatic search/replace of data/code.
  2113.  
  2114. Same use as HexReplaceLong().
  2115.  
  2116. The search will be done word by word (2 bytes). Odd occurences will not be found.
  2117.  
  2118. See also: HexReplaceLong()
  2119.  
  2120.  
  2121.  
  2122.  
  2123. JOTDStartup/SetFakeFunction()
  2124.  
  2125.  
  2126. void SetFakeFunction(offset, new function) - Sets user defined function in fakeexec table
  2127.                        D0       A0
  2128.  
  2129. The exec library emulation is poor. You'll have to define your own functions to make
  2130. it better (game specific or not).
  2131.  
  2132. For instance, if a game uses AllocMem(), it's up
  2133. to you to choose what to return, to keep track of the allocated blocks or not
  2134. (is it worth? is AllocMem() called more than once, twice...?)
  2135.  
  2136. You could do it in a "dirty" way, by getting FakeExecBase in $4 and patching the offset,
  2137. but I created a function for this. As a bonus, the function will check:
  2138.  
  2139. 1. That you pass an offset which is between 0 and -$300
  2140. 2. That OpenFakeExec() was called (before SaveOSData)
  2141.  
  2142. If both conditions are not passed, the function will trigger an explicit run-time error.
  2143.  
  2144. Example: define your own AvailMem()
  2145.  
  2146.        ...
  2147.        
  2148.        lea    MyOwn_AvailMem(pc),A0
  2149.        GETLVO AvailMem
  2150.        JSRGEN SetFakeFunction
  2151.        ...
  2152.  
  2153. MyOwn_AvailMem:
  2154.        move.l   #$70000,D0
  2155.        rts
  2156.  
  2157. I used my new macro GETLVO to get an LVO in D0. (move.l  #_LVO1,D0)
  2158.  
  2159. See also: OpenFakeExec()
  2160.  
  2161.  
  2162.  
  2163.  
  2164. JOTDStartup/CRC16()
  2165.  
  2166.  
  2167. UWORD CRC16 (buffer, length) - Calculates CRC16 checksum
  2168.  D0             A0       D0
  2169.  
  2170. This routine calculates CRC16 checksum of a block according to the
  2171. ANSI CRC16 algorithm.
  2172.  
  2173. Thanks to Andreas Kleiner for putting the crc.c source on aminet,
  2174. which I converted into assembler (available on request)
  2175.  
  2176. This routine was added because of the WHDLoad slave emulation.
  2177.  
  2178.  
  2179.  
  2180.  
  2181. JOTDStartup/HexToString()
  2182.  
  2183.  
  2184. void HexToString(number,buffer) - Converts a hex number to a ascii string
  2185.                    D0    A1
  2186.  
  2187. The buffer has to be at least as wide as 10 chars. The format will always be:
  2188.  
  2189. $xxxxxxxx.
  2190.  
  2191. e.g: D0=$37 gives A1-> $00000037
  2192.      D0=$DEADBEEF gives A1-> $DEADBEEF
  2193.  
  2194.  
  2195.  
  2196.  
  2197. JOTDStartup/Save & Restore hardware registers
  2198.  
  2199.  
  2200. void SaveCustomRegs() - Save readable custom registers
  2201. void RestoreCustomRegs() - Restore previously saved custom registers
  2202. void SaveCIARegs() - Save CIA registers
  2203. void RestoreCIARegs() - Restore CIA registers
  2204.  
  2205. Those functions are used internally to save/restore intena, intreq, adkcon
  2206. dmacon, and the CIA registers from/to the operating system.
  2207. So the game can (and will) trash those registers, but they will be restored
  2208. when InGameExit() is called.
  2209. You should not use those functions, unless you know what you are doing.
  2210.  
  2211. See also: InGameExit(), SaveOSData(), SAVE_OSDATA (macro)
  2212.  
  2213.  
  2214.  
  2215.  
  2216. JOTDStartup/RNCLength()
  2217.  
  2218.  
  2219. ULONG RNCLength(memory) - returns the length of a decrunched RNC file
  2220.  D0              A0
  2221.  
  2222. This function returns 0 if the zone pointed by A0 is not a RNC crunched file.
  2223. Else, it will return the number of bytes the file will take once decrunched.
  2224.  
  2225. See also - LoadRNCFile(), RNCDecrunch()
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231. JOTDStartup/RNCDecrunch()
  2232.  
  2233.  
  2234. ULONG RNCDecrunch(crunchbuffer,decrunchbuffer) - Decrunches a RNC type 1 file
  2235.  D0                   A0            A1
  2236.  
  2237. This routine handles Rob Northen Cruncher files (header: RNC01).
  2238. This type of cruncher is very heavily used in lots of games
  2239. from EOA, Team 17, Renegade, Akklaim, and lots of others.
  2240.  
  2241. A0 points on the crunched buffer start (the file just loaded), and
  2242. A1 points on the destination.
  2243.  
  2244. This routine returns 0 if an error occured.
  2245.  
  2246. The two addresses may be the same, as the decrunch algorithm is able to
  2247. overwrite the crunched data during decrunch.
  2248. Be careful to allocate or reserve enough memory to decrunch the file.
  2249. Use the RNCLength() function to know the length of the file once decrunched.
  2250.  
  2251. LoadRNCFile uses this routine, but RNCDecrunch can be useful when the game is NONDOS
  2252. and the data is trackloaded.
  2253.  
  2254. NOTE: RNC crunched files are handled by the XFD library (decrunch only)
  2255. The cruncher (ProPack) is not freely distributable, and reserved to
  2256. game programmers.
  2257.  
  2258. See also - LoadRNCFile(), RNCLength(), RNCDecrunchEncrypted(), ATNDecrunch()
  2259.  
  2260.  
  2261.  
  2262.  
  2263. JOTDStartup/RNCDecrunchEncrypted()
  2264.  
  2265.  
  2266. ULONG RNCDecrunchEncrypted(key,crunchbuffer,decrunchbuffer) - Decrunches a RNC type 1 file, with encryption
  2267.  D0                         D0      A0            A1
  2268.  
  2269. Some games, like Walker, use RNC compression, but encrypt data with a 16/32
  2270. bit key. You'll need to know the key to be able to decrunch the file
  2271. properly. In most cases, leave the game handle that. I use this routine
  2272. because in most games the decrunch routines are located in chipmem and it's
  2273. slow. You can patch the entry of a RNC decrunch routine by this call,
  2274. which is in fastmem, and you'll be amazed by the speed.
  2275.  
  2276. See also - LoadRNCFile(), RNCLength(), RNCDecrunch(), ATNDecrunch(), PPDecrunch(),
  2277.            FungusDecrunch()
  2278.  
  2279.  
  2280.  
  2281.  
  2282. JOTDStartup/ATNDecrunch()
  2283.  
  2284.  
  2285. ULONG ATNDecrunch(crunchbuffer,decrunchbuffer) - Decrunches a ATN! file
  2286.  D0                   A0            A1
  2287.  
  2288. This routine handles ATN files (header: ATN!).
  2289. This type of cruncher is very heavily used in lots of games
  2290. from Team 17 (Arcade Pool, Project-X...)
  2291.  
  2292. A0 points on the crunched buffer start (the file just loaded), and
  2293. A1 points on the destination.
  2294.  
  2295. This routine returns 0 if an error occured.
  2296.  
  2297. The two addresses may be the same, as the decrunch algorithm is able to
  2298. overwrite the crunched data during decrunch.
  2299. Be careful to allocate or reserve enough memory to decrunch the file.
  2300. Use the ATNLength() function to know the length of the file once decrunched.
  2301.  
  2302.  
  2303. NOTE: ATN crunched files are handled by the XFD library (decrunch only)
  2304. The cruncher is not available. This cruncher no longer appears in
  2305. Team 17 games and has been replaced by RNC.
  2306.  
  2307. See also - LoadRNCFile(), RNCLength(), RNCDecrunchEncrypted()
  2308.  
  2309.  
  2310.  
  2311.  
  2312. JOTDStartup/PPDecrunch()
  2313.  
  2314.  
  2315. PPDecrunch(end_crunchbuf,start_crunchbuf,decrunchbuf) - Decrunches a PP20 file
  2316.               A0              A1            A2
  2317.  
  2318. As I saw this routine in at least one game and I know PowerPacker 
  2319. by Nico François is very popular on the amiga, I included this decrunch routine.
  2320.  
  2321. This applies to file beginning by the PP20 header (PowerPacker 2.0)
  2322.  
  2323. in: A0 end of source buffer
  2324.     A1 start of dest buffer
  2325.     A2 start of source buffer
  2326.  
  2327. out: nothing, but the buffer is decrunched :-)
  2328.  
  2329. All registers are preserved in this call.
  2330.  
  2331. See also - RNCDecrunch(), ATNDecrunch(), FungusDecrunch()
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337. JOTDStartup/FungusDecrunch()
  2338.  
  2339.  
  2340. void FungusDecrunch(crunchbuf,decrunchbuf) - Decrunches a FUNGUS file
  2341.                        A0          A1
  2342.  
  2343. The FUNGUS packer (maybe also called SF or SA packer) is mostly used
  2344. in Gremlins games (Zool, Switchblade 2...)
  2345.  
  2346. in: A0: crunched buffer start
  2347. in: A1: destination (may be the same, like in RNC decruncher)
  2348.  
  2349. CAUTION: This decrunch routine does not check that the data is correct.
  2350. Unreliable results may occur if you try to decrunch a random block of memory.
  2351.  
  2352. See also - RNCDecrunch(), ATNDecrunch(), PPDecrunch()
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358. JOTDStartup/BlackScreen()
  2359.  
  2360.  
  2361. void BlackScreen() - Sets all the colors to black
  2362.  
  2363. This function will not build a copperlist. It will just clear color registers.
  2364.  
  2365.  
  2366.  
  2367.  
  2368. JOTDStartup/EnterDebugger()
  2369.  
  2370.  
  2371. void EnterDebugger(void) - Enters debugger if one is installer
  2372.  
  2373. ATM only HRTMon is property supported. A version of HRTMon which works is for instance
  2374. 2.22. All versions above this one work too.
  2375.  
  2376. EnterDebugger calls the debugger just as if you put a breakpoint there, except that
  2377. you don't have too :)
  2378. VERY useful function when the loader is in development phase, to remove afterwards!
  2379.  
  2380. This function will do nothing if no debugger was found. Run JST with VERBOSE or TEST on
  2381. to see which debugger is currently loaded.
  2382.  
  2383. See also: 
  2384.  
  2385.  
  2386.  
  2387.  
  2388. JOTDStartup/SetTraceVector()
  2389.  
  2390.  
  2391. APTR SetTraceVector(APTR trace_entrypoint) - sets trace vector to a user routine
  2392.  A0                  A0
  2393.  
  2394. Now that JST relocates the VBR (unless you use the VBR-specific tooltypes), it's no
  2395. longer possible to poke directly in the trace exception vector to install a tracer
  2396. by poking in $24, since JST will intercept the trace exception with the relocated VBR.
  2397.  
  2398. This function allows to do it transparently.
  2399.  
  2400. in: A0 points to your trace code. Of course it's up to you to preserve registers on exit.
  2401.     Exit by RTE (not RTS)
  2402.  
  2403. out: A0 points to the old trace code. Most of the time it's the routine JST installed.
  2404.  
  2405. See also: 
  2406.  
  2407.  
  2408.  
  2409.  
  2410. JOTDStartup/WaitMouse()
  2411.  
  2412.  
  2413. void WaitMouse(void) - Waits for LMB while the screen is full of colors
  2414.  
  2415. Useful to see if a point is reached. Waits until the LMB is pressed to exit.
  2416.  
  2417.  
  2418. See also: WaitMouseInterrupt()
  2419.  
  2420.  
  2421.  
  2422.  
  2423. JOTDStartup/WaitMouseInterrupt()
  2424.  
  2425.  
  2426. void WaitMouseInterrupt(void) - Waits for LMB while the screen is full of colors, interrupts active
  2427.  
  2428. Same routine as WaitMouse() except that as a bonus, interrupts will be enabled during the
  2429. wait, allowing you to break with a software debugger like HRTMon.
  2430.  
  2431. But this function can lead to crashes in some cases (e.g. the interrupts were disabled
  2432. because the interrupts vectors were not set by the game yet)
  2433.  
  2434. See also: WaitMouse()
  2435.  
  2436.  
  2437.  
  2438.  
  2439. JOTDStartup/InGameExit()
  2440.  
  2441.  
  2442. void InGameExit() - returns to the OS while the game is running
  2443.  
  2444. This function will return with a rts if no memory was available
  2445. for the chipmem (SaveOSData()). The best way to call it is from
  2446. a JSRGEN, then return to the program if it could not quit.
  2447.  
  2448. This function was moved from the absolute part to the relocatable part
  2449. in order to avoid crashes when the absolute program has be overridden
  2450. by the game. JSRABS InGameExit will not work (it will not crash in
  2451. most cases but will do nothing).
  2452.  
  2453. Now you can call this function before having called SaveOSData()
  2454. or the SAVE_OSDATA macro from the user program.
  2455.  
  2456. Call it whenever you want during the game, even if the OS
  2457. is totally killed. This function will resurrect the OS and will
  2458. call the user routine you specified using the SetExitRoutine function
  2459. if any. (see macro HDPARAMS)
  2460.  
  2461. This function has be greatly improved. It succeeds on 99.9% of games.
  2462.  
  2463. See also: SaveOSData(), InGameOSCall()
  2464.  
  2465.  
  2466.  
  2467.  
  2468. JOTDStartup/IsRegistered()
  2469.  
  2470.  
  2471. ULONG IsRegistered(void) - Check if the current version of JST is registered
  2472.   D0
  2473.  
  2474. Returns 0 in D0 if the version of JST currently used is not registered
  2475. Returns 1 in D0 if the version of JST currently used is registered (from v1.1e)
  2476.  
  2477. See also: 
  2478.  
  2479.  
  2480.  
  2481.  
  2482. JOTDStartup/SetExitRoutine()
  2483.  
  2484.  
  2485. void SetExitRoutine(routine entrypoint) - calls a user routine on exit
  2486.                           A0
  2487.  
  2488. This function will allow the user to specify a function to call
  2489. when the OS has been restored with InGameExit(). For instance, this function
  2490. can save scores to a file without the use of WriteFileHD but in a normal DOS
  2491. way, or can display a message, free some manually allocated memory...
  2492.  
  2493. If you want to save scores on exit which are located in chip memory,
  2494. remember that you'll have to copy the scores in fastmem before calling
  2495. InGameExit, or the buffer will be trashed by the OS chipmem.
  2496.  
  2497. The user routine must end by RTS.
  2498.  
  2499. CAUTION: The input was D0 and now it's A0 because it's more convenient for
  2500. relocatable code.
  2501.  
  2502. See also: InGameExit()
  2503.  
  2504.  
  2505.  
  2506.  
  2507. JOTDStartup/InGameIconify()
  2508.  
  2509.  
  2510. void InGameIconify() - returns to the OS while the game is running, with possibility of return
  2511.  
  2512. This function acts exactly like InGameExit BUT it allows to return to the game!
  2513. That seems impossible to do because of the read only registers, that's why some special
  2514. functions are to be applied on the game before you can use this function.
  2515.  
  2516. Actually, JST is already able to swap the OS but the display, because the copper pointer
  2517. is ready only.
  2518. But you can use some other functions to patch the game at some strategic locations
  2519. when it stores the copperlist pointer into the copper pointer register (COP1LC, $80).
  2520.  
  2521. Those functions modify the MOVE instruction which are used to store the
  2522. copperlist pointer very easily.
  2523.  
  2524. Copperlist pointer store can be of these types:
  2525.  
  2526. 1: move.l Ax,($80,Ay)
  2527. 2: move.l #chipaddr,($80,Ay)
  2528. 3: move.l addr,($80,Ay)
  2529. 4: move.l #chipaddr,$DFF080
  2530. 5: move.l addr,$DFF080
  2531. 6: move.l Ax,$DFF080
  2532.  
  2533. There are many ways to store a copperlist pointer, but those are the most frequent occurences.
  2534.  
  2535. --
  2536.  
  2537. CASE 1:
  2538.  
  2539. To search (and patch) case 1, you can use HexReplaceLong() because this instruction is
  2540. 4 bytes long and is totally determined once you found which registers the game is using
  2541. (with HRTMon just search with fi and the pattern A*,($80,A*) )
  2542.  
  2543. Replace the instruction by $4EB8addr where $addr is a zero page address where you can
  2544. put the storage code or put a PATCHUSRJMP to a user routine (I prefer that second solution)
  2545.  
  2546. Be careful of the range, and check the locations you patch are actually copper moves
  2547. (just ensure Ay contains $DFF000), or else the iconify could go bezerk
  2548. (but the game will still work)
  2549.  
  2550. In that use routine, you'll put the value in the copper pointer and register it to JST
  2551. using the SetCopperPointer() function. You've done it.
  2552.  
  2553. This is the most difficult and manual case, but when you're used to it, that's not a concern
  2554. anymore.
  2555.  
  2556. CASE 2:
  2557.  
  2558. You lucky guys I made a special search and patch routine for those frequent occurences.
  2559. It's called PatchMoveCList_Idx(). There are a couple of parameters
  2560. but it's very easy to use and totally transparent.
  2561. You've got to put it at the right place, that's all.
  2562.  
  2563.  
  2564. CASE 3:
  2565.  
  2566. Like in case 2, I also made a routine called PatchMoveCList_Abs()
  2567.  
  2568. CASE 4:
  2569.  
  2570. Like in case 2, I also made a routine called PatchMoveCList_Ind()
  2571.  
  2572. CASE 5:
  2573.  
  2574. No routine implemented in JST. Totally manual method. I may add a PatchMoveCList_xxx function
  2575. later but now I don't feel like doing it.
  2576.  
  2577. CASE 6:
  2578.  
  2579. Well, totally manual method, but easy. Note down the addresses, and then make a PATCHUSRJSR
  2580. to your user routine (the instruction is also 6 bytes long)
  2581. which will do the poke in the copperlist register and will log
  2582. the copper pointer value to JST using SetCopperPointer().
  2583.  
  2584. --
  2585.  
  2586. If you cannot find in copperlist store instruction belonging to those 6 cases above, 
  2587. you'll have to search further, but game coders usually don't hide this kind
  2588. of instruction too much (it can happen, though, when sometimes they try to fool
  2589. the Action Replay cartridges).
  2590.  
  2591. You've got another solution if you don't find the copperlist pointer: look into the game
  2592. using Action Replay cartridge (or equivalent) or do a copper search with HTRMon.
  2593. If the copperlist location does not move, you can hardcode it in your program and call
  2594. SetCopperPointer() with this address.
  2595.  
  2596.  
  2597. When you logged all the copperlist pointer store instructions, InGameIconify can be called
  2598. exactly like InGameExit, using for instance the TAB key in the keyboard interrupt.
  2599.  
  2600. In some cases, you'll have to set some hardware registers 'by hand' after JST resumes the game.
  2601. For instance, I had to put a move.w #$400F,fmode+$DFF000 in Street Racer, or else the display
  2602. was trashed.
  2603. But in some games like Menace or Lotus, the iconification works perfectly.
  2604.  
  2605. InGameIconify won't do anything if the current copperlist pointer is set to 0.
  2606. You can set it to this value with StoreCopperPointer()
  2607.  
  2608. See the examples (Menace, Street Racer, Lotus Turbo Challenge) to figure out how to do
  2609. this.
  2610.  
  2611. Warning: QUIET will prevent this function to work. It will do nothing in that case. Just
  2612. because JST uses the console in the iconify menu.
  2613.  
  2614. See also: InGameExit(), StoreCopperPointer(), TellCopperPointer(), PatchMoveCList_Idx(),
  2615.           PatchMoveCList_Abs(), HexReplaceLong()
  2616.  
  2617.  
  2618.  
  2619.  
  2620. JOTDStartup/PatchMoveCList_Abs()
  2621.  
  2622.  
  2623. void PatchMoveCList_Abs(start, end, trap_number) - patches copper list stores: move.l #adr,$DFF080
  2624.                          A0     A1     D1
  2625.  
  2626. This function puts a TRAP when it finds a MOVE.L #ADR,$DFF080 instruction.
  2627. ADR is checked so no patch is done if ADR is not in chipmem.
  2628.  
  2629. If D1 is out of $0-$F range, this function will do nothing. You can usually choose any of those
  2630. numbers (which match trap numbers location $80 ->$BC), but some games use some traps, and
  2631. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2632. In that case, you've got to patch manually.
  2633.  
  2634. A0: start address: MUST BE AN EVEN ADDRESS!
  2635. A1: end address
  2636. D1: trap number ($0-$F)
  2637.  
  2638. This function flushes the caches at the end of the operation.
  2639.  
  2640. See also: PatchMoveCList_Idx(), PatchMoveCList_Ind(), InGameIconify()
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646. JOTDStartup/PatchMoveCList_Ind()
  2647.  
  2648.  
  2649. void PatchMoveCList_Ind(start, end, trap_number) - patches copper list stores: move.l adr,$DFF080
  2650.                          A0     A1     D1
  2651.  
  2652. This function puts a TRAP when it finds a MOVE.L ADR,$DFF080 instruction.
  2653. ADR is checked so no patch is done if ADR is not in chipmem.
  2654.  
  2655. If D1 is out of $0-$F range, this function will do nothing. You can usually choose any of those
  2656. numbers (which match trap numbers location $80 ->$BC), but some games use some traps, and
  2657. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2658. In that case, you've got to patch manually.
  2659.  
  2660. A0: start address: MUST BE AN EVEN ADDRESS!
  2661. A1: end address
  2662. D1: trap number ($0-$F)
  2663.  
  2664. This function flushes the caches at the end of the operation.
  2665.  
  2666. See also: PatchMoveCList_Idx(), PatchMoveCList_Abs(), InGameIconify()
  2667.  
  2668.  
  2669.  
  2670.  
  2671.  
  2672. JOTDStartup/PatchMoveCList_Idx()
  2673.  
  2674.  
  2675. void PatchMoveCList_Idx(start, end, register#, trap#) - patches copper list stores: move.l #adr,($80,Ax)
  2676.                          A0     A1     D0       D1
  2677.  
  2678. This function puts a TRAP when it finds a MOVE.L #ADR,($80,Ax) instruction if the
  2679. register number you specified matches Ax. It stores the copper pointer so InGameIconify
  2680. knows where it is.
  2681.  
  2682. ADR is checked so no patch is done if ADR is not in chipmem.
  2683.  
  2684. This function will do nothing if D1 is out of $0-$F range or if D0 is out of 0-6 range.
  2685. Most of the time, you can choose any of those numbers $0-$F for D1
  2686. (which match trap numbers location $80 ->$BC) but some games use some traps, and
  2687. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2688. In that case, you've got to patch manually (hard luck!)
  2689.  
  2690. A0: start address: MUST BE AN EVEN ADDRESS!
  2691. A1: end address
  2692. D0: register number (0-6)
  2693. D1: trap number ($0-$F)
  2694.  
  2695. This function flushes the caches at the end of the operation.
  2696.  
  2697. See also: PatchMoveCList_Abs(), PatchMoveCList_Ind(), InGameIconify()
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703. JOTDStartup/PatchMoveBlit_Idx()
  2704.  
  2705.  
  2706. void PatchMoveBlit_Idx(start, end, register#, trap#) - patches blit moves: move.w #adr,($58,Ax)
  2707.                         A0     A1     D0       D1
  2708.  
  2709. This function puts a TRAP when it finds a MOVE.W #ADR,($58,Ax) instruction if the
  2710. register number you specified matches Ax.
  2711. The trap performs the blit but calls WaitBlit() before, so the
  2712. blitter is always ready and there are no blitter errors due to those calls.
  2713.  
  2714. This function will do nothing if D1 is out of $0-$F range or if D0 is out of 0-6 range.
  2715. Most of the time, you can choose any of those numbers $0-$F for D1
  2716. (which match trap numbers location $80 ->$BC) but some games use some traps, and
  2717. obviously you cannot use the same ones. You'd be very unlucky if the game used ALL the traps.
  2718. In that case, you've got to patch manually (hard luck!)
  2719.  
  2720. A0: start address: MUST BE AN EVEN ADDRESS!
  2721. A1: end address
  2722. D0: register number (0-6)
  2723. D1: trap number ($0-$F)
  2724.  
  2725. This function flushes the caches at the end of the operation.
  2726.  
  2727. See also: WaitBlit()
  2728.  
  2729.  
  2730.  
  2731.  
  2732.  
  2733. JOTDStartup/StoreCopperPointer()
  2734.  
  2735.  
  2736. void StoreCopperPointer(cptr) - Logs the current (believed) copperlist pointer to JST
  2737.                          D0
  2738.  
  2739. D0 can be guessed or read from an instruction in the game.
  2740.  
  2741. Passing -1.L to this function will disable Iconification (JST believes the copperlist
  2742. is not known anymore)
  2743.  
  2744. See also: InGameIconify(), TellCopperPointer(), PatchMoveCList_Abs(), PatchMoveCList_Idx()
  2745.  
  2746.  
  2747.  
  2748.  
  2749. JOTDStartup/TellCopperPointer()
  2750.  
  2751.  
  2752. ULONG TellCopperPointer(void) - Returns the current logged copperlist pointer
  2753.  D0   
  2754.  
  2755. Gets current copperlist pointer if you had logged the copperlist moves.
  2756.  
  2757. This function will return -1.L if the copperlist has not been logged yet.
  2758.  
  2759. See also: InGameIconify(), TellCopperPointer(), PatchMoveCList_Abs(), PatchMoveCList_Idx()
  2760.  
  2761.  
  2762.  
  2763.  
  2764. JOTDStartup/BeamDelay()
  2765.  
  2766.  
  2767. void BeamDelay(beamticks) - waits using VPOSR register
  2768.                   D0.W
  2769.  
  2770. This function will wait approx. D0*20ms.
  2771. Use it to fix some CPU dependent loops like
  2772.  
  2773. loop
  2774. dbf Dx,loop
  2775.  
  2776. by dividing Dx by #$28 and calling BeamDelay
  2777. with value of Dx in D0
  2778. (problem mentionned by Harry in some Soundtracker replay routines)
  2779.  
  2780. move.w Dx,D0
  2781. divu #$28,D0
  2782. swap D0
  2783. clr.w D0
  2784. swap D0
  2785. JSRGEN BeamDelay
  2786. (or  BEAM_DELAY D0)
  2787.  
  2788.  
  2789. See also: BEAM_DELAY (macro)
  2790.  
  2791.  
  2792.  
  2793.  
  2794. JOTDStartup/WaitBlit()
  2795.  
  2796.  
  2797. void WaitBlit(void) - waits for blitter operations to complete
  2798.  
  2799. This small routine, inserted at the proper location, allows to avoid
  2800. blitter gfx bugs in loads of games (DoodleBug, Premiere, James Pond,
  2801. Ninja Spirit...)
  2802. and avoid crashes due to those blitter bugs (Lotus I, Lotus III, X-Out...)
  2803.  
  2804. You can either insert it before the blit (better) or after the blit
  2805. (safer, but can slowdown the game)
  2806.  
  2807. A blit is a write access to register $DFF058. See the JOTDHDInstall.guide
  2808. to learn how to find those faulty blits.
  2809.  
  2810. See also: WAIT_BLIT (macro)
  2811.  
  2812.  
  2813.  
  2814.  
  2815. JOTDStartup/SetQuitKey()
  2816.  
  2817.  
  2818. void SetQuitKey(key,user_routine) - Activates auto quit key
  2819.                 D0       A0
  2820.  
  2821. D0: raw keycode
  2822. A0: user routine to be called before InGameExit
  2823.  
  2824. If A0=0, then no user routine will be called (default exit)
  2825.  
  2826. Note: Ralf prefered this feature to be reserved to registered users only. That's his
  2827. will, and since he coded the stuff, I only have to agree.
  2828.  
  2829. If QUITKEY tooltype is set, SetQuitKey will use the QUITKEY tooltype value instead of
  2830. the loader built-in value.
  2831.  
  2832. See also: SAVEOS_DATA (macro), SetIconifyKey()
  2833.  
  2834.  
  2835.  
  2836.  
  2837. JOTDStartup/SetIconifyKey()
  2838.  
  2839.  
  2840. ULONG SetIconifyKey(key,user_routine) - Activates auto iconify key
  2841.  D0                  D0       A0
  2842.  
  2843. D0: raw keycode (if D0 is 0 no iconify will be attempted)
  2844. A0: custom code which will be called:
  2845.  *before* InGameIconify with D0 = 0
  2846.  *after* InGameIconify with D0 = 1
  2847.  
  2848. If A0=0, then no user routine will be called.
  2849.  
  2850. If the Custom code returns with D0 != 0 no iconify will be performed
  2851.  
  2852.  
  2853. Remember that installing a iconify feature on a loader is tricky.:)
  2854.  
  2855. Note: Ralf prefered this feature to be reserved to registered users only. That's his
  2856. will, and since he coded the stuff, I only have to agree. If used with a non-registered
  2857. JST, this routine will do nothing.
  2858.  
  2859. If QUITKEY tooltype is set, SetQuitKey will use the QUITKEY tooltype value instead of
  2860. the loader built-in value.
  2861.  
  2862. See also: InGameIconify(), SetQuitKey()
  2863.  
  2864.  
  2865.  
  2866.  
  2867. JOTDStartup/LogPatch()
  2868.  
  2869.  
  2870. void LogPatch(address,length) - tells JST the patches you're going to do
  2871.                 A0      D0
  2872.  
  2873. PATCHUSRJSR, PATCHUSRJMP, PATCH_RTS, PATCHGENJSR and PATCHGENJMP include this function
  2874. automatically if PATCH_LOGGED variable is set.
  2875.  
  2876. LogPatch saves D0 bytes of the memory at location A0. Useful to save the bytes you
  2877. patch upon.
  2878.  
  2879. The log file is called "patch.log". It is saved on exit in the current directory
  2880. or the directory specified by SAVEDIR. This logfile can be analysed using the
  2881. printlog tool.
  2882.  
  2883. See also: InitLogPatch, REGISTER_PATCH (macro)
  2884.  
  2885.  
  2886.  
  2887.  
  2888. JOTDStartup/InitLogPatch()
  2889.  
  2890.  
  2891. void InitLogPatch(void) - Initializes patch logging
  2892.  
  2893. Internal use. Called if the PATCH_LOGGED constant is defined in your loader BEFORE
  2894. the jst.i include.
  2895.  
  2896. See also: LogPatch, REGISTER_PATCH (macro)
  2897.  
  2898.  
  2899.  
  2900.  
  2901. JOTDStartup/The printlog tool
  2902.  
  2903.  
  2904. This tool is used to turn the binary patch.log files into viewable text.
  2905. This is very useful to update loaders to newer versions, which are generally
  2906. slightly different than the one you're already done...
  2907.  
  2908. Usage:
  2909.  
  2910. printlog <logfile> [<sourcefile>] [NOZPAGE]
  2911.  
  2912. logfile (compulsory): the logfile generated with JST (patch.log)
  2913. sourcefile (optionnal): put your asm source file here. When a patch address is found,
  2914.     printlog makes a "grep" in your sourcefile and displays the line used to patch this location
  2915.     of course your sourcefile is NEVER written into.
  2916. NOZPAGE: does not show zero page patches matches in the sourcefile (if you patched in $D0, you
  2917.     can have a trifle of lines matched :) )
  2918.  
  2919. Redirect the output to a file to see the patches you applied.
  2920.  
  2921. See also: LogPatch(), REGISTER_PATCH
  2922.  
  2923.  
  2924.  
  2925.  
  2926.